如果你不想增加你的池的大小,并假设你正确地返回每个SocketAsyncEventArgs
使用后,您可以使用一个BlockingCollection来保存所需数量的SocketAsyncEventArgs
。当物品返回到收藏时,消费者会阻止没有更多物品需要消费。
更新
下面是创建大小1和火灾的BlockingCollection
关闭一些消费者能够同时处理一些示例代码。每个消费者从集合中取出一个物品进行处理,同时其他人在Take
上被封锁,直到物品被添加回集合。
处理时,您可能需要在try/finally
块中执行此操作,以确保在处理该项目后,如果抛出异常,则始终会重新添加该项目。
要关闭呼叫CompleteAdding()
和收集任何遮挡Take
方法将抛出一个InvalidOperationException
public void RunConsumer(BlockingCollection<SocketAsyncEventArgs> collection, int consumerId)
{
Task.Run(async() =>
{
Console.WriteLine("Consumer {0} waiting", consumerId);
SocketAsyncEventArgs args = null;
try
{
args = collection.Take();
Console.WriteLine("Consumer {0} processing", consumerId);
await Task.Delay(5000);
}
catch(ObjectDisposedException)
{
Console.WriteLine("Consumer {0} collection has been disposed", consumerId);
}
catch(InvalidOperationException)
{
Console.WriteLine("Consumer {0} collection has been closed", consumerId);
}
finally
{
// add the item back if collection hasn't been closed.
if(args != null && !collection.IsAddingCompleted)
collection.Add(args);
}
Console.WriteLine("Consumer {0} finished", consumerId);
});
}
使用
void Main()
{
var collection = new BlockingCollection<SocketAsyncEventArgs>(1) { new SocketAsyncEventArgs() };
RunConsumer(collection, 1);
RunConsumer(collection, 2);
RunConsumer(collection, 3);
Thread.Sleep(9000);
collection.CompleteAdding();
Console.ReadLine();
}
输出
Consumer 1 waiting
Consumer 3 waiting
Consumer 2 waiting
Consumer 1 processing
Consumer 1 finished
Consumer 3 processing
Consumer 2 collection has been closed
Consumer 2 finished
Consumer 3 finished
所以你很乐意等到SocketAsyncEventArgs变得可用? –
我试过了!我编辑了SocketAsyncEventArgsPool类的Pop()函数: – user2964559