Gyrien
Gyrien

Reputation: 317

When can BlockingCollection<T> TryTake() return false?

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

Answers (2)

Sven Grosen
Sven Grosen

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

Henk Holterman
Henk Holterman

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

Related Questions