C# 尝试与消费
解决方案1和2之间的区别是什么?\u taskQ是BlockingCollection,我正在尝试实现生产者-消费者场景。BlockingCollection将默认的ConcurrentQueue用于内部存储C# 尝试与消费,c#,blockingcollection,C#,Blockingcollection,解决方案1和2之间的区别是什么?\u taskQ是BlockingCollection,我正在尝试实现生产者-消费者场景。BlockingCollection将默认的ConcurrentQueue用于内部存储 //Solution 1 foreach (Action action in _taskQ.GetConsumingEnumerable()) { action(); // Perform task. Thread.Sleep(1000); } 尝试在没有项目时创建块 /
//Solution 1
foreach (Action action in _taskQ.GetConsumingEnumerable())
{
action(); // Perform task.
Thread.Sleep(1000);
}
尝试在没有项目时创建块
//Solution 2
Action t;
while(_taskQ.TryTake(out t))
{
t();
Thread.Sleep(1000);
}
bool TryTake(out T)
如果没有项目,则立即返回false。bool TryTake(out T,TimeSpan)
如果超时期间没有项目,则返回false。
getconsumineGenumerable()
返回的可枚举项在没有项时阻塞,直到生产者调用CompleteAdding()
在解决方案1中,您等待下一个操作并执行它;一个合适的模式!但是Thread.Sleep()
实际上并不是必需的,因为如果没有任何项,迭代将被阻止
在解决方案2中,您在有动作时采取并执行动作,然后如果消费者领先于生产者,则退出循环。这可能不是您想要的。为什么不使用
System.Threading.Task
并执行类似的Task.Run(异步委托{wait Task.Delay(1000);})代码>@MethodMan你为什么要在后台拖延?只需等待任务。延迟(1000)代码>您的假设不正确。迭代器将等待一个项出现在集合中。但当集合为空时,TryTake()返回false。调用Sleep()从来都不是避免烧掉100%内核的好方法,您会更喜欢迭代器。删除Sleep()调用。@MethodMan,您的意思是用Task.Run替换Thread.Sleep(1000)?Task.Run在线程池上运行委托,因此它不会作为Thread.Sleep(1000)阻塞。