【问题标题】:When can BlockingCollection<T> TryTake() return false?BlockingCollection<T> TryTake() 什么时候可以返回 false?
【发布时间】:2014-01-17 20:25:45
【问题描述】:

假设 BlockingCollection 在下面使用 ConcurrentQueue,如果您使用 Timeout.Infinite,TryTake(T, Int32) method 什么时候可以返回 false?

【问题讨论】:

  • 您链接到的文档包含您问题的答案。你在寻找什么答案?一个具体的例子?会失败的代码?文档清楚地说明了导致该方法抛出的原因。
  • 或者,你问的是什么时候它会返回false而不是抛出异常?
  • @ledbutter 这就是我要问的,我已经更新了 OP。
  • @elgonzo 那么在这种情况下,除了 msdn 链接中列出的异常之外,它不会返回 false 吗?

标签: c# collections concurrency


【解决方案1】:

这是一个简单的例子,它显示了它何时可以返回 false:当集合被标记为 CompleteAdding 并变为空时

//by default, BlockingCollection will use ConcurrentQueue
BlockingCollection<int> coll = new BlockingCollection<int>();

coll.Add(1);
coll.Add(2);
coll.CompleteAdding();

int item;

if (coll.TryTake(out item, -1))
{
    Console.WriteLine(item);
}

if (coll.TryTake(out item, -1))
{
    Console.WriteLine(item);
}

if (coll.TryTake(out item, -1))
{
    //this won't get hit
}
else
{
    Console.WriteLine("TryTake returned false!");
}

这允许您禁止在队列中添加新项目并完成剩余元素的处理

【讨论】:

  • 如果不使用 .CompleteAdding() 触发,它不会返回 false,对吗?
  • @Gyrien 正确,但它永远不会超过最后一次 TryTake 调用(假设您使用无限超时),因为它会在那里等待,直到您发出已完成添加到集合的信号.
【解决方案2】:

这将打印false

 var coll = new BlockingCollection<int>();            

 coll.CompleteAdding();   // closed for business

 int v;
 bool result = coll.TryTake(out v, Timeout.Infinite);

 Console.WriteLine(result);

所以基本上 BlockingCollection 支持 2 个独立的概念:空和封闭。虽然 TryTake() 可以在空队列上永远等待,但当队列同时为空已关闭时,它将返回 false

【讨论】:

  • 如果不使用 .CompleteAdding() 触发,它不会返回 false,对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-21
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多