What is a real world use for ConcurrentBag<T>?
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.
Dustin Davis
Microsoft MVP, PostSharp MVP, MCTS c0deporn: http://www.c0deporn.com
Updated on June 05, 2022Comments
-
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 almost 13 yearsYou 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 almost 13 years@Dustin: Good question. I was thinking of
ConcurrentHashMultiset
(the Java equivalent ofConcurrentBag
) when I was writing my answer, which does have aremove
method. I have no idea what the .NETConcurrentBag
class is good for, then. :-P -
Dustin Davis almost 13 yearsThats ok, based on your answer I was able to come up with a real world scenario applicable to my self.
-
M.Babcock over 11 yearsFrom the description, this sounds like it would be better implemented using layered queues (possibly
ConcurrentQueue
orBlockingCollection
instances) rather than theConcurrentBag
class. There appears to be a fair amount of overlap between the class usage though so I may be mistaken. -
Şafak Gür almost 9 yearsThis is a case for a thread-safe hashset - which can be created using an underlying
ConcurrentDictionary
.