Add collection to BlockingCollection
Asked Answered
P

2

6

BlockingCollection contains only methods to add individual items. What if I want to add a collection? Should I just use foreach loop?

Why BlockingCollection doesn't contain method to add a collection? I think such method can be pretty useful.

Peursem answered 8/9, 2012 at 8:26 Comment(0)
S
8

ICollection interfaces and many of the BCL list-type classes don't have an AddRange method for some reason and it is annoying.

Yes, you'll need to foreach over the collection, you could write you own extension method if you're using it a lot.

Support answered 8/9, 2012 at 8:32 Comment(1)
What's even more annoying is that they don't even extend the generic ICollection<T> which at least contains an Add method. The ICollection interface doesn't, so you have to write separate extension methods for every collection type.Phineas
M
0

The BlockingCollection<T> is a wrapper of an underlying collection that implements the IProducerConsumerCollection<T> interface, which by default is a ConcurrentQueue<T>. This interface has only the method TryAdd for adding elements. It doesn't have a TryAddRange. The reason is, I guess, because not all native IProducerConsumerCollection<T> implementation are equipped with AddRange functionality. The ConcurrentStack<T> does have the PushRange method, but the ConcurrentQueue<T> doesn't have something equivalent.

My understanding is that if this API existed, it would have atomic semantics. It wouldn't be just a convenience method for reducing the code needed for doing multiple non-atomic insertions. Quoting from the ConcurrentStack<T>.PushRange documentation:

When adding multiple items to the stack, using PushRange is a more efficient mechanism than using Push one item at a time. Additionally, PushRange guarantees that all of the elements will be added atomically, meaning that no other threads will be able to inject elements between the elements being pushed. Items at lower indices in the items array will be pushed before items at higher indices.

Atomicity is especially important when adding in a blocking-stack, because the item that is added can be immediately taken by another thread that is currently blocked. If I add the items A, B and C with the order C-B-A, it's because I want the A to be placed at the top of the stack, and picked by another thread first. But since the additions are not atomic, another thread could win the race and take the C before the current thread manages to add the B and the A. According to my experiments this happens rarely, but there is no way to prevent it. In case it is absolutely necessary to enforce the insertion order, there is no other option than implementing a custom BlockingStack<T> collection from scratch.

Minaminabe answered 11/2, 2023 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.