Does foreach remove from C# BlockingCollection?

2.3k views Asked by At

does anyone know if, when iterating on a C# BlockingCollection<>, the elements are taken from the collection, in the same way that BlockingCollection.Take() does for example?

BlockingCollection<int> q = new BlockingCollection<int>();
[...]
foreach(int i in q)
{
    //does q still contain i?
}

Thanks

EDIT: Of course I meant BlockingCollection, but for some reason got BlockingQueue in my head and used that.

3

There are 3 answers

0
Matthew Watson On BEST ANSWER

The BlockingCollection<T> enumerator does NOT remove items from the collection.

However, the enumerator returned from BlockingCollection<T>.GetConsumingEnumerable() DOES remove items from the collection.

6
John Saunders On

foreach simply enumerates across a collection. It never removes anything from any collection.

0
dcastro On

There is no BlockingQueue<T> in the .NET libraries.

Assuming

  1. You're talking about BlockingCollection<T>: No. using foreach calls the GetEnumerator method, which returns an IEnumerator. Standard implementations of an IEnumerator simply enumerate through the elements in the collection without any observable side effects. Since MSDN doesn't say otherwise regarding BlockingCollection<T> specifically, it is safe to assume that this specific implementation also has no observable side effects.

  2. You're talking about a third-party library: You'll have to check its implementation, but I think it's safe to assume it doesn't remove anything from the collection.

Edit: Actually, because BlockingCollection wraps around an IProducerConsumerCollection<T>, BlockingCollection uses the enumerator of the underlying (internal) collection. None of the IProducerConsumerCollection<T> implementations provided by .NET modify the collection.