TryTake vs GetConsumingEnumerable

时间:2016-02-04 16:15:58

标签: c# blockingcollection

解决方案1和2有什么区别,_taskQ是BlockingCollection,我正在尝试实现Producer-Consumer方案。 BlockingCollection使用默认的ConcurrentQueue进行内部存储。

//Solution 1
foreach (Action action in _taskQ.GetConsumingEnumerable())
{
    action(); // Perform task.
    Thread.Sleep(1000);
}

没有项目时,TryTake会阻止

//Solution 2
Action t;
while(_taskQ.TryTake(out t))
{
    t();
    Thread.Sleep(1000);
}

1 个答案:

答案 0 :(得分:7)

如果没有项目,

bool TryTake(out T)会立即返回false 如果超时期限内没有项目,则bool TryTake(out T, TimeSpan)返回false。 在GetConsumingEnumerable()生成器调用CompleteAdding()之前,Thread.Sleep()块返回的可枚举块没有任何项目。

在解决方案1中,您等待下一个操作并执行它;一个合适的模式!但{{1}}并不是必需的,因为如果没有任何项目,迭代将会阻止。

在解决方案2中,您可以在有任何操作时执行并执行操作,然后在消费者领先于生产者时退出循环。这可能不是你想要的。