我有一个应用程序,它使用字符串队列(对应于应用程序需要执行的不同任务)。随机时刻队列可能会被填充字符串(有时每分钟几次,但也可能需要几个小时)。
到目前为止,我总是有一个定时器,每隔几秒钟检查队列是否有项目,并将其删除。
我认为必须有比这种方式更好的解决方案。是否有任何方法可以在将项目添加到队列时获取事件或类似的内容?
到目前为止,我总是有一个定时器,每隔几秒钟检查队列是否有项目,并将其删除。
我认为必须有比这种方式更好的解决方案。是否有任何方法可以在将项目添加到队列时获取事件或类似的内容?
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);
}
}
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);
}