当 BlockingCollection 为空时,我从BlockingCollection的 TryTake 方法返回false,尽管预期的行为是阻塞,直到集合填满为止。
请注意,集合不是上限(这应该影响TryAdd而不是TryTake),并且没有为add操作设置超时。
这是我在BlockingCollection对象周围的包装器:
public T TryTake(int timeoutMiliseconds)
{
var result = default(T);
if (!_collection.TryTake(out result, timeoutMiliseconds))
{
throw new InvalidOperationException("Unable to get item from collection.");
}
return result;
}
任何可能导致这种情况的想法?
我已经基于这篇文章实现了Producer-Consumer模式: Multithread processing of the SqlDataReader - Producer/Consumer design pattern
答案 0 :(得分:0)
我终于意识到,正如SO post所示,我从TryTake
中弄错了因为集合已被清空,并且我也标记为已完成(通过调用CompleteAdding()
方法集合)。
因此,为了解决这个问题,我在已完成的旗帜上添加了条件。
有人可能会说TryTake
永远不会返回 false ,而已完成的标记 false 。我不确定它总是正确的,所以我更倾向于在这种情况下抛出错误。
public T TryTake(int timeoutMiliseconds)
{
var result = default(T);
if (!_collection.TryTake(out result, timeoutMiliseconds)
&& !_collection.IsAddingCompleted)
{
throw new InvalidOperationException("Unable to get item from collection.");
}
return result;
}
请注意,首先TryTake
调用和IsAddingCompleted
秒调用至关重要。否则,第一个条件可能会过去,您将在TryTake
之后立即阻止。