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