Does foreach remove from C# BlockingCollection?
Asked Answered
B

3

6

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.

Boffa answered 6/12, 2013 at 11:16 Comment(0)
N
14

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.

Nerva answered 6/12, 2013 at 11:24 Comment(0)
R
2

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

Rancourt answered 6/12, 2013 at 11:19 Comment(6)
And actually if I'm not mistaken, manipulating the collection inside a foreach is forbidden and will fail at runtime.Propose
That is simply not true. Consider, for example, using foreach with BlockingCollection<T>.GetConsumingEnumerable() The issue is that because foreach simply calls methods in IEnumerator<T> the effect depends on the specific implementation of IEnumerator<T> that's being called - so you can make no claims about what the effect of using foreach will be.Nerva
Sorry, Matthew, you're wrong. foreach isn't removing anything - it's the IEnumerator<T> which is removing items in this very specific and very unusual case.Rancourt
Using foreach can have the side-effect of removing items from a collection, which is my point. I think this point is important in the context of the OP's question which wasn't "does foreach remove elements from a collection?" but rather "when iterating on a C# BlockingQueue<>, are elements taken from the collection?"Nerva
@MatthewWatson: name one other enumerator that removes from a standard collection. This possibility is simply not worth mentioning.Rancourt
The OP seems to be talking about a BlockingCollection (although he referred to it as a BlockingQueue) so my opinion is that this is definitely relevant and therefore it is indeed worth mentioning. I agree in the general case (i.e. ALL other cases!) then it isn't relevant. But I'm responding to the OP's actual question rather than something theoretical.Nerva
H
0

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.

Heterogeneity answered 6/12, 2013 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.