What is a real world use for ConcurrentBag<T>?

12,201

Solution 1

Bags are really useful for tracking instance counts. For example, if you want to keep a record of which hosts you're servicing web requests for, you can add their IP to the bag when you start servicing the request, and remove it when done.

Using a bag will allow you to tell at a glance which IPs you're currently servicing. It will also let you quickly query whether you're servicing a given IP address.

If you use a set for this rather than a bag, then having multiple concurrent requests from the same IP address will mess up your record-keeping.

Solution 2

Because there is no ordering the ConcurrentBag has a performance advantage over ConcurrentStack/Queue. It is implemented by Microsoft as local thread storage. So every thread that adds items does this in it's own space. When retrieving items they come from the local storage. Only when that is empty the thread steals item from another threads storage. So instead of a simple list a ConcurrentBag is a distributed list of items. And is almost lockfree and should scale better with high concurrency.

Unfortunately in .NET 4.0 there was a performance issue (fixed in 4.5) see http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0

Solution 3

Anything where you just need to keep track of what's there and don't need random access or guaranteed order. If you have a thread that adds items to process, and a thread that removes items in order to process them, a concurrent bag would work well if you don't care that they're processed in FIFO order.

Solution 4

Thanks to @Chris Jester-Young I came up with a good, real world, scenario that actually applies to a project i'm working on.

Find - Process - Store

Find - threads 1 & 2 are set to find or scrape data (file system, web, etc). These results are stored in ConcurrentBag1.

Process - threads 3 & 4 are set to take out of ConcurrentBag1, clean/transform/process the data and then store the results in ConcurrentBag2.

Store - threads 5 is set to gather results from ConcurrentBag2 and store the results in SQL.

Share:
12,201
Dustin Davis
Author by

Dustin Davis

Microsoft MVP, PostSharp MVP, MCTS c0deporn: http://www.c0deporn.com

Updated on June 05, 2022

Comments

  • Dustin Davis
    Dustin Davis almost 2 years

    A ConcurrentBag will allow multiple threads to add and remove items from the bag. It is possible that a thread will add an item to the bag and then end up taking that same item right back out. It says that the ConcurrentBag is unordered, but how unordered is it? On a single thread, the bag acts like a Stack. Does unordered mean "not like a linked list"?

    What is a real world use for ConcurrentBag?

  • Dustin Davis
    Dustin Davis almost 13 years
    You say add their IP to the bag and then remove it when done. How do you remove a specific item from a bag?
  • C. K. Young
    C. K. Young almost 13 years
    @Dustin: Good question. I was thinking of ConcurrentHashMultiset (the Java equivalent of ConcurrentBag) when I was writing my answer, which does have a remove method. I have no idea what the .NET ConcurrentBag class is good for, then. :-P
  • Dustin Davis
    Dustin Davis almost 13 years
    Thats ok, based on your answer I was able to come up with a real world scenario applicable to my self.
  • M.Babcock
    M.Babcock over 11 years
    From the description, this sounds like it would be better implemented using layered queues (possibly ConcurrentQueue or BlockingCollection instances) rather than the ConcurrentBag class. There appears to be a fair amount of overlap between the class usage though so I may be mistaken.
  • Şafak Gür
    Şafak Gür almost 9 years
    This is a case for a thread-safe hashset - which can be created using an underlying ConcurrentDictionary.