Geeks With Blogs

News

Vitaly Dilmukhametov

.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! :)

Posted on Saturday, October 24, 2009 10:20 AM Parallel Extension , .NET , data , concurrency | Back to top


Comments on this post: Thread-safe data structures .NET 4.0 (part 1)

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
So, guy, you're really geek!
Left by Sergey Zwezdin on Oct 24, 2009 5:41 AM

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

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

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
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 ;-)
Left by Vitaly Dilmukhametov on Oct 25, 2009 3:08 AM

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
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 ;)
Left by Sergey Zwezdin on Oct 25, 2009 3:13 AM

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
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 )
Left by Vitaly Dilmukhametov on Oct 25, 2009 3:26 AM

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
Hehe. The post about thread-safe structures contains the deep hidden meaning.
Left by Sergey Zwezdin on Oct 25, 2009 3:29 AM

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
Yep! Especially in this so philosophical day! =)
Left by Vitaly Dilmukhametov on Oct 25, 2009 3:48 AM

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

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

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

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
Great!
PSG is the best person for walking to store for cookies now! :)))
Left by Vitaly Dilmukhametov on Oct 25, 2009 4:08 AM

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
Hennessy first!
Left by Sergey Popov on Oct 25, 2009 4:22 AM

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

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
Hennessy + Cookies is so strange. :)
Left by Sergey Zwezdin on Oct 25, 2009 4:25 AM

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

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

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

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
Hi, typo!

About which collection are you talking?
Can you provide some piece of code, where IsEmpty == true for non-empty concurrent collection?
Left by Vitaly Dilmukhametov on Oct 26, 2009 7:37 AM

# re: Thread-safe data structures .NET 4.0 (part 1)
Requesting Gravatar...
>>ConcurrentBag: I think, it’s a most simple data structure:
It is far from simple, it's a distributed concurrent scaleable collection. It stores items in threadlocal storage so it is almost lockfree. It steals items from other threads when the local storage is empty and the local thread wants an item from it.
Left by Ivo Tops on Jul 20, 2012 7:51 PM

Your comment:
 (will show your gravatar)


Copyright © Vitus | Powered by: GeeksWithBlogs.net