当新项目进入队列时,如何退出队列

本文关键字:队列 何退出 退出 新项目 | 更新日期: 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);
   }