Reputation: 317
Assuming the BlockingCollection is using a ConcurrentQueue underneath, when could the TryTake(T, Int32) method return false if you are using Timeout.Infinite?
Upvotes: 6
Views: 6918
Reputation: 5636
Here's a simple example that shows when it can return false: when the collection is marked as CompleteAdding
and becomes emptу
//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!");
}
This allows you to forbid adding new items in queue and complete processing of remaining elements
Upvotes: 14
Reputation: 273274
This will print false
:
var coll = new BlockingCollection<int>();
coll.CompleteAdding(); // closed for business
int v;
bool result = coll.TryTake(out v, Timeout.Infinite);
Console.WriteLine(result);
So basically a BlockingCollection supports 2 separate concepts: Empty and Closed. And while TryTake() can wait forever on an Empty queue, when the queue is both Empty and Closed it will return false
.
Upvotes: 7