How to remove all items from ConcurrentBag?

How to clear ConcurrentBag ? it has no method like Clear or RemoveAll ...

+56
c # concurrency
Mar 21 '11 at 12:01
source share
5 answers
 T someItem; while (!myBag.IsEmpty) { myBag.TryTake(out someItem); } 
+26
Mar 21 2018-11-21T00:
source share

Update 03/10/2017: As @Lou correctly points out, the assignment is atomic. In this case, creating a ConcurrentBag will not be atomic, but including this link in the variable will be atomic - therefore, locking or Interlocked.Exchange around it is strictly not required.

Further reading:

Link assignment is atomic, so why do I need Interlocked.Exchange (ref Object, Object)?

Is the referential assignment thread safe?




You can always block access to the bag itself and create a new copy. Then the items in the bag will be available for GC, if nothing else holds on to them:

 lock (something) { bag = new ConcurrentBag(); } 

Or, as Lucasoid points out:

 var newBag = new ConcurrentBag(); Interlocked.Exchange<ConcurrentBag>(ref bag, newBag); 

An easy way to unload the content, however, this assumes that whenever the element wants to access, it also gets a lock - this can be expensive and may negate the performance tuning that got into the ConcurrentBag itself.

If you know that at this time nothing else will be available in the bag, it will be closed and will not block :-)

+48
Mar 21 '11 at 12:39
source share

The selected answer is a kind of, well, workaround, so I am adding my own workaround.

My solution was to look at all available collections in the System.Collections.Concurrent namespace to find the one where it was trivial to clear all items from the collection.

The ConcurrentStack class has a Clear () method that removes all items from the collection. In fact, this is the only collection in the namespace (currently). Yes, you should Push(T element) instead of Add(T element) , but to be honest, it's worth it to save time.

+16
Jun 26 '13 at 18:04 on
source share

You can delete an object one at a time in a loop:

 object result; while (bag.TryTake(out result)); 

Please note that after this cycle the package cannot be empty, because the elements can be added after the completion of the cycle and before the next operation using another thread.

+9
Mar 21 2018-11-21T00:
source share

In the spirit of workarounds .. ConcurrentDictionary<T, bool> has atomic Clear, but also allows you to quickly check if a key exists. Fast is a relative term, but depending on your use, it may be faster than listing a large stack.

+4
Sep 12 '14 at 13:01
source share



All Articles