English | 中文 | Русский | Français
2,856 Posts served
8,606 Conversations started
One of the most difficult tasks related to concurrent programming in C# and .Net 3.5 is sharing collections, arrays or lists between many tasks running at the same time. Besides, the complexity increases when these concurrent tasks need to add and/or remove items from them. Doing this safely involves a great control of coordination data structures and the efficient use of precise locks.
One of the most well-known examples is a producer-consumer scheme. On one side, a producer, running in one thread, must add elements to a collection, array or list. On the other side, a producer, running concurrently in another thread, must remove elements from the same collection, array or list. Handling these situations is indeed very complex for the most brave developers and software engineers.
Luckily, the June 2008 CTP (Community Technology Preview) of Parallel Extensions to the .Net Framework added very interesting high-level coordination data structures and thread-safe collections. The result is amazing: the producer-consumer scheme complexity reduced to a minimum.
Using these amazing high-level thread-safe collections and a good design, it is possible to add and remove items from collections letting Parallel Extensions manage the necessary locks and low-level coordination stuff. The design is simplified and the code is easier to read. The concurrent collections manage the complex work and the developers focus in what they need to do using high levels of concurrency safely.
These usage of these concurrent collections imply a coordination cost, but they are very easy to use and they avoid lots of head-aches. Believe me.
These are the three concurrent collections initially added by June 2008 CPT, which are also going to be available as part of .Net 4.0 in Visual Studio 2010:
• System.Threading.Collections.BlockingCollection: Provides blocking and bounding capabilities.
• System.Threading.Collections.ConcurrentQueue: Represents a variable size first-in-first-out (FIFO) collection.
• System.Threading.Collections.ConcurrentStack: Represents a variable size last-in-first-out (LIFO) collection.
They are included in the System.Threading.Collections namespace and they implement the common System.Threading.Collections.IConcurrentCollection interface.
Using them, you can easily handle many concurrent tasks running their threads adding and removing elements from a thread-safe shared collection. Hence, it is easier than ever to create multiple chained producer-consumer schemes taking full advantage of 4 or 8 cores. Besides, it is possible to have multiple threads adding elements and multiple threads removing elements, concurrently.
For example, in a ConcurrentQueue, the items can be added safely using the Enqueue method and they can be safely removed using the TryDequeue method.
There are three new structures to be added in .Net 4.0: ConcurrentBag; ConcurrentLinkedList and ConcurrentLinkedListNode. I haven't had the opportunity to work with them yet. I'll tell you about them in another post.
It sounds easy. It is. However, there are many other considerations to take into account, related to concurrency, immutability and thread-safe code. Nevertheless, you’ll love these concurrent collections in .Net 4.0.
Comments and feedback are always welcome.
| April 9, 2009 11:16 AM PDT
Gastón C. Hillar
|
Hi Dmitriy, It's good to see your comments in my post. :) So far, Parallel Extensions are entering Beta 1. I must tell you this before adding my comment, because it can change in future releases. Take into account that Parallel Extensions do not have the same power than TBB (Threading Building Blocks). They still have many limitations. However, working with concurrent collections is a nice step ahead. We didn't have that possibility in the .Net runtime in C# 3.0 and it required hard work to do that. Nowadays, in order to create atomic transactions like the ones you talk about, you have to work with the CCR (Concurrency and Coordination Runtime) and you have to develop your own customized coordinated atomic transaction. In this link, you will find an excellent article about this topic in MSDN Magazine, called "Concurrent Affairs", written by Jeffrey Richter. Link: http://msdn.microsoft.com/en-us/magazine/cc163556.aspx Cheers, Gastón |
| April 12, 2009 12:20 AM PDT
Dmitriy Vyukov
|
Thank you! |
| September 10, 2009 7:00 AM PDT
jonas |
Hi, I'm looking forward in using these!! What I'd really like would be some FIFO.Dequeue(IfCondition) that is thread safe. Like an built in atomic lock { if (Peek().Y == Condition) Dequeue() } |

Dmitriy Vyukov
27,142
Status Points:
27,142
Does Parallel Extensions offer something for this problem?