我不完全理解所有.Net异步编程概念(等待,异步,等待,同步上下文等)是如何工作的。
我正在使用套接字,它们需要缓冲区来进行读/写操作,我想要一个BufferAllocator对象来搜索并返回套接字要使用的缓冲区。关键是当没有足够的可用内存(缓冲池为空)时,应用程序应等待缓冲区并在所需的内存量可用时继续。
我该如何实现?
好的,这是我的作业(为了简单起见只是一个演示,这不是我真正的代码):
class Program
{
private static BufferAllocator _allocator;
static void Main(string[] args)
{
_allocator = new BufferAllocator(100); // 100 bytes
Task.Factory.StartNew(async () =>
{
await _allocator.GetBufferAsync(40); // 100 - 40 = 60bytes
await _allocator.GetBufferAsync(40); // 60 - 40 = 20bytes
await _allocator.GetBufferAsync(40); // 20 < 40 (wait)
Console.WriteLine("Worked!"); // <-------+
}); // |
Console.ReadKey(); // |
_allocator.ReleaseBuffer(40); // after pessing a key, release 40 bytes
Console.ReadKey();
}
}
class BufferAllocator
{
private int _availableBytes;
private SemaphoreSlim _signal = new SemaphoreSlim(0, 1);
public BufferAllocator(int bufferSize)
{
_availableBytes = bufferSize;
}
public async Task GetBufferAsync(int size)
{
while(_availableBytes < size)
await _signal.WaitAsync();
_availableBytes -= size;
}
public void ReleaseBuffer(int size)
{
_availableBytes += size;
_signal.Release();
}
}
注意:将有几个插槽并行读写。请给我一个线索。
答案 0 :(得分:3)
当您实际实现async
构造时,您应该使用TaskCompletionSource
。将其视为信号对象。它具有Task
属性,您可以异步返回到客户端await
。并使用TaskCompletionSource
方法更新任务的状态(例如SetResult
)。这就是一方(生产者)&#34;通知&#34;应该恢复的另一个(该特定任务的消费者)。
当然,您可以使用内置构造(如SemaphoreSlim
,基于大小或AsyncAutoResetEvent
)。
确保永远不会忘记完成任务(结果,例外或取消)。否则你将面临最令人不快的错误/死锁。