当新项目进入队列时,如何退出队列
本文关键字:队列 何退出 退出 新项目 | 更新日期: 2023-09-27 18:06:49
我有一个应用程序,它与字符串队列(对应于应用程序需要执行的不同任务)一起工作。在随机时刻,队列可以被字符串填满(比如有时一分钟几次,但也可能需要几个小时)。
到目前为止,我总是有一个计时器,每隔几秒钟检查队列中是否有项目,并删除它们。
我想一定有比这种方法更好的解决办法。当一个项目被添加到队列中时,是否有任何方法可以获得一个事件?
是。看看TPL数据流,特别是BufferBlock<T>
,它或多或少地做了与BlockingCollection
相同的事情,而没有利用async/await
阻塞线程的讨厌的副作用。
所以你可以:
void Main()
{
var b = new BufferBlock<string>();
AddToBlockAsync(b);
ReadFromBlockAsync(b);
}
public async Task AddToBlockAsync(BufferBlock<string> b)
{
while (true)
{
b.Post("hello");
await Task.Delay(1000);
}
}
public async Task ReadFromBlockAsync(BufferBlock<string> b)
{
await Task.Delay(10000); //let some messages buffer up...
while(true)
{
var msg = await b.ReceiveAsync();
Console.WriteLine(msg);
}
}
我会看看BlockingCollection.GetConsumingEnumerable。默认情况下,集合将使用队列来支持,并且在使用简单的foreach
循环添加值时自动从队列中获取值是一种很好的方法。
还有一个重载允许您提供CancellationToken
,这意味着您可以干净地跳出
你看过BlockingCollection
吗?GetConsumingEnumerable()
方法允许在消费者上运行一个无限循环,一旦一个物品可用,就会产生新的物品,而不需要计时器,或者Thread.Sleep's
:
//常见:
BlockingCollection<string> _blockingCollection =
new BlockingCollection<string>();
//制作人
for (var i = 0; i < 100; i++)
{
_blockingCollection.Add(i.ToString());
Thread.Sleep(500); // So you can track the consumer synchronization. Remove.
}
//消费者:
foreach (var item in _blockingCollection.GetConsumingEnumerable())
{
Debug.WriteLine(item);
}