TryTake 与 GetConsumingEnumerable

TryTake vs GetConsumingEnumerable

解决方案 1 和 2 有什么区别,_taskQ 是 BlockingCollection,我正在尝试实现生产者-消费者场景。 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);
}

bool TryTake(out T) returns 如果没有项目则立即返回 false。
bool TryTake(out T, TimeSpan) returns 如果在超时期限内没有项目,则为 false。 GetConsumingEnumerable() 返回的枚举在没有任何项目时会阻塞,直到生产者调用 CompleteAdding()

在解决方案1中,您等待下一个动作并执行它;合适的图案!但是 Thread.Sleep() 并不是真正必要的,因为如果无论如何都没有项目,迭代将阻塞。

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