C# 从BlockingCollection中获取项目的正确方式是什么?
调用BlockingCollection.Take()时,集合的IsCompleted状态可能会在检查IsCompleted和调用Take()之间发生更改 显示一个示例的示例只捕获了无效操作异常,但似乎必须有一种正确的方法在不捕获异常的情况下执行此类调用(因为这会产生相当大的开销,并且代码看起来不干净)。调用.Take()和避免无效操作异常的正确方法是什么 我的特定问题的简化版本:C# 从BlockingCollection中获取项目的正确方式是什么?,c#,.net,generics,collections,synchronization,C#,.net,Generics,Collections,Synchronization,调用BlockingCollection.Take()时,集合的IsCompleted状态可能会在检查IsCompleted和调用Take()之间发生更改 显示一个示例的示例只捕获了无效操作异常,但似乎必须有一种正确的方法在不捕获异常的情况下执行此类调用(因为这会产生相当大的开销,并且代码看起来不干净)。调用.Take()和避免无效操作异常的正确方法是什么 我的特定问题的简化版本: If (!blockingCollection.IsCompleted) { //do some stuff va
If (!blockingCollection.IsCompleted)
{
//do some stuff
value = blockingCollection.Take(); //Throws Exception, IsCompleted = True;
}
有一个TryTake方法可用,但我的印象是,它可以传递超时和取消令牌,而不是在检查IsCompleted和调用Take()之间处理IsCompleted变为true。您可以使用。如果
BlockingCollection
为空或已标记为已完成,它将返回false,并正确处理您面临的同步问题。当集合为空时调用TryTake时,我会收到InvalidOperationException。。。(使用超时很难,但时间确实没有过去)。为什么会这样?@ilans,如果你看一下文档,它说InvalidOperationException发生在TryTake中,“底层集合在这个BlockingCollection实例之外被修改了。”