调用BlockingCollection.Take()时,集合的IsCompleted状态可能会在IsCompleted检查和Take()调用之间发生变化。
显示示例的MSDN Documentation只捕获了无效的操作异常,但似乎必须有一种正确的方法来执行此类调用而不捕获异常(因为这会导致相当大的开销并且不会在代码中看起来很干净。调用.Take()和避免无效操作异常的正确方法是什么?
我特定问题的简化版本:
If (!blockingCollection.IsCompleted)
{
//do some stuff
value = blockingCollection.Take(); //Throws Exception, IsCompleted = True;
}
有一种TryTake方法可用,但我的印象是它可以传入超时和取消令牌,而不是处理IsCompleted在检查时和Take时之间变为真(被称为。
答案 0 :(得分:14)
您可以使用TryTake overload with no timeout/cancelation。如果BlockingCollection
为空或已标记为已完成,它将返回false,并处理您正确面对的同步问题。