The Task Parallel Library and System.Collections.Concurrent Namespace

Arguably one of the biggest parts of .NET 4.0 was the Task Parallel Library (TPL). The TPL makes it ridiculously easy to parallelize code. With Parallel.ForEach, Parallel.For, Parallel.Invoke, and Task.Factory developing for today’s multi-core systems should be a matter of fact.

Recently I was tasked with optimizing a large code base to utilize the TPL. The first problem? List and Dictionary aren’t thread safe. That’s right, two of the most common data structures aren’t thread safe. Fortunately we’ve been provided with alternatives that are thread safe in the System.Collections.Concurrent Namespace.

The biggest difference I’ve seen between using List and using one of the alternatives, ConcurrentBag is that you can’t access items in a ConcurrentBag via an indexer. The truth, however, is that alternative methods are provided via LINQ extension methods.

Consider:

ConcurrentBag<int> myBag = new ConcurrentBag<int>();

var task1 = Task.Factory.StartNew(() =>
    {
        LongRunningMethod();
        myBag.Add(1);
    });

var task2 = Task.Factory.StartNew(() =>
    {
        LongRunningMethod();
        myBag.Add(2);
    });

var task3 = Task.Factory.StartNew(() =>
    {
        LongRunningMethod();
        myBag.Add(3);
    });

Task.WaitAll(task1, task2, task3);
Parallel.For(0, myBag.Count, i => 
{
    Debug.Print(myBag.ElementAt(i).ToString());
});

List<int> myList = new List<int>();
LongRunningMethod();
myList.Add(1);
LongRunningMethod();
myList.Add(2);
LongRunningMethod();
myList.Add(3);
for (int i = 0; i < myList.Count; i++)
{
    Debug.Print(myList[i].ToString());
}

resulted in the output:

1
3
2
1
2
3

with, obviously, the parallel methods being faster.

The other problem we ran into is manipulation of visuals. As I’m sure you know manipulation of visuals is required to be on the main thread. Otherwise you start getting all sorts of permission issues. The minute you start having to move doing things on the main thread you lose the advantages you gained by moving towards all this parallelism. Future projects will move towards the MVVM pattern but past projects we’ll have to work on what we can.

Leave a Reply