Vitaly Dilmukhametov

  Home  |   Contact  |   Syndication    |   Login
  17 Posts | 0 Stories | 66 Comments | 0 Trackbacks

News

Archives

Post Categories

.NET 4 contains rich set of tools, that allow to create parallelized code more easy. But when we start processing chunk of data in parallel threads, we need to synchronize these threads, and we need some storage for the results of work. Now exist a big number of methods, solving sync issues, and we can realize in code any of them. But MS Parallel Extensions team already do it, and .NET 4 beta versions include set of thread-safe data structures. They implement some popular types of collections, and I want to do an overview of them.

1. Queue: ConcurrentQueue<T>

This is a classic FIFO queue, which can be safely accessed from few threads simultaneously. API of this collection is very simple:

ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
queue.Enqueue(10);
 
int t;
Console.WriteLine(queue.TryPeek(out t));
Console.WriteLine(queue.TryDequeue(out t));
TryPeek() and TryDequeue() methods return an element from queue, but TryPeek() doesn’t remove it from queue. Both methods returns true, if they take an element, else they return false. You can add an element by calling Enqueue() method. Count of elements in the queue you can get by Count property, and if collection contains at least 1 element, property IsEmpty returns true.
 
2. Stack: ConcurrentStack<T>
 

This is a simple LIFO stack, that can be used in the concurrent environment. In contrast to queue, you can easily add or take the range of elements:

ConcurrentStack<int> stack = new ConcurrentStack<int>();
stack.Push(10);
stack.PushRange(new int[] { 1, 2, 3, 4, 5 });
 
int t;
if (stack.TryPop(out t))
{
    Console.WriteLine("Pop: " + t);
}
if (stack.TryPeek(out t))
{
    Console.WriteLine("Peek: " + t);
}
int[] ts = new int[5];
int count;
if ((count = stack.TryPopRange(ts, 0, 3)) > 0)
{
    Console.WriteLine("PopRange");
    for (int i = 0; i < count; i++)
    {
        Console.WriteLine(ts[i]);
    }
}

 

Here is the result of work of this code:

image

TryPeek() and TryPop() methods return bool values, and TryPopRange() – count of retrieved elements. You may add range of values by calling PushRange() method.

3. Collection: ConcurrentBag<T>

This is an unordered collection of data, which is looks like a set, but it can store duplicate items. It doesn’t guarantee any order of elements. I think, it’s a most simple data structure:

ConcurrentBag<int> bag = new ConcurrentBag<int>(new int[] { 1, 1, 2, 3 });
bag.Add(70);
 
int t;
bag.TryPeek(out t);
Console.WriteLine(t);
 
bag.Add(110);
 
Console.WriteLine();
for (int i = 0; i < 3; i++)
{
    bag.TryTake(out t);
    Console.WriteLine(t);
}

 

This piece of code produce following console output:

image

Looking at screenshot, you can notice, that elements retrieved in LIFO. I repeat: no any orders is guaranteed.

Take a look at the constructor of bag – you can set initial range of elements, and constructors of queue and stack have appropriate overloads too.

4. Dictionary: ConcurrentDictionary<TKey, TValue>

It’s just a variant of Dictionary<TKey, TValue>, which can be accessed concurrently. API for this collection has some thread-safe specific features:

ConcurrentDictionary<string, string> dict = new ConcurrentDictionary<string, string>();
dict.TryAdd("name", "OFC340");
dict.TryAdd("age", "25");
dict.TryAdd("age", "25");

 

Create/update/delete actions can be executed by calling one of Try* methods, which return true on success, else false. In the code sample, first attempt to add value “25” with key “age” is ok, and TryAdd return true. Second attempt is fail, and TryAdd() return false, and exception will not be generated. Other example:

string t = string.Empty;
Console.WriteLine(dict.TryGetValue("nokey", out t));

Key “nokey” is not present in the dictionary, but TryGetValue() method doesn’t generate any exception, and only return false. You can remove an element as shown here:

Console.WriteLine(dict.TryRemove("age", out t));

Using properties Values and Keys you can receive actual on the moment of call collections of values and keys of dictionary.

So, you can see, that these data structures is very basic, and don’t contains tons of functions – only necessary things. I like this concept – it’s a base structures and too many functions is redundant. If you need something else, you can easily add it at any time.

In addition to described data structures, .NET 4 beta 1 contains list ConcurrentLinkedList<T>. But I don’t cover it, because MSDN contains following warning: «ConcurrentLinkedList(of T) is planned to be removed prior to the final release of Visual Studio 2010. Please do not use this class». And in the .NET 4 beta 2 this collection is removed.

Ok, I show you 4 basic thread-safe collections of data. In the next part of the article I show you BlockingCollection<T> – more complex and interest thread-safe storage. Stay tuned! :)

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted on Saturday, October 24, 2009 10:20 AM

Feedback

# re: Thread-safe data structures .NET 4.0 (part 1) 10/24/2009 5:41 AM Sergey Zwezdin
So, guy, you're really geek!

# re: Thread-safe data structures .NET 4.0 (part 1) 10/24/2009 8:06 AM Vitaly Dilmukhametov
Hey, Sergey!
I'm not more geekly then you ;-)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 3:02 AM Sergey Zwezdin
Hm. You are mistaken.
I'm simple MVP, but you are MOST GEEKly guy of all geeks in the World.

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 3:08 AM Vitaly Dilmukhametov
Jeez! I'm not a "backshtag" =)))

And you are not a simple MVP. All of us, include my readers know that you a MSRD, and it's a fact!

So, don't break out, guy ;-)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 3:13 AM Sergey Zwezdin
You aren't "back sh tag". What is it? The "sh" tag? Hm, strange.
Yes, I'm simple MSRD, but we know that you are not simple guy and it's fact too.
Looks like that you're simply modest guy and because you speak that you are not the "maniac". But we know the truth and you are really geek ;)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 3:26 AM Vitaly Dilmukhametov
Yep! I'm very-very modest, it's a real truth. And you, Sergey, are more modest than me - it's starts early, I think from school =))
P.S. I don't believe - the post about thread-safe collections can cause these comments )

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 3:29 AM Sergey Zwezdin
Hehe. The post about thread-safe structures contains the deep hidden meaning.

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 3:48 AM Vitaly Dilmukhametov
Yep! Especially in this so philosophical day! =)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:01 AM Sergey Zwezdin
Philosophical day it's a snow day.
Thank you very much for your geekly articles. And sorry :))))))))))

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:04 AM Vitaly Dilmukhametov
Ok, guy. But you'll go to the store for some tasty cookies ;-)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:06 AM Sergey Zwezdin
So, I think that psg will go to store for buy tasty cookies.
What do you think about it?

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:08 AM Vitaly Dilmukhametov
Great!
PSG is the best person for walking to store for cookies now! :)))

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:22 AM Sergey Popov
Hennessy first!

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:24 AM Sergey Zwezdin
Sergey, ok. You want to buy Hennessy first? Ok. Go! :)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:25 AM Sergey Zwezdin
Hennessy + Cookies is so strange. :)

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:29 AM Vitaly Dilmukhametov
Ok, guys!
Hennessy is a real choice, but I'm really more like tea with cookies now :) So, you can take a both!

# re: Thread-safe data structures .NET 4.0 (part 1) 10/25/2009 4:35 AM Sergey Zwezdin
Hm. Cookies + Tea + Hennessy it's so more strange choice. I'd like tea+cookies too. Sergey, what you?

# re: Thread-safe data structures .NET 4.0 (part 1) 10/26/2009 7:26 AM typo
and if collection contains at least 1 element, property IsEmpty returns true

# re: Thread-safe data structures .NET 4.0 (part 1) 10/26/2009 7:37 AM Vitaly Dilmukhametov
Hi, typo!

About which collection are you talking?
Can you provide some piece of code, where IsEmpty == true for non-empty concurrent collection?

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: