Tuesday, September 23, 2014

Thread Safe Collections in .Net

Recently, I have been creating multi-threaded applications with the need of having collections, to manage processed items by threads.
In .Net, we have the great collection classes, such as:
  • System.Collections.Generic.List
  • System.Collections.Queue
  • System.Collections.Stack
... and many others.

So, codes like this:


    class Program
    {
        static Queue Numbers = new Queue();

        static void Main(string[] args)
        {
            Thread[] t = new Thread[10];
            for (int i = 0; i < 10; i++)
            {
                t[0] = new Thread(() => { for (int a = 0; a < 200; a++) Numbers.Enqueue(a); });
                t[0].Start();
            }
            while (t[0].IsAlive) { }
        }
    }


Return Exceptions like this:


An unhandled exception of type 'System.ArgumentException' occurred in System.dll

Additional information: Destination array was not long enough. Check destIndex and length, and the array's lower bounds

After some research, I came to the solution. Turns out, these collections are not Thread Safe. But Microsoft has provided us some thread safe collections in System.Collections.Concurrent namespace.

The variable above could be replaced by:

static ConcurrentQueue<int> Numbers = new ConcurrentQueue<int>();


And this will work like a charm.

Also, ConcurrentQueue has a different method for Deque.

Instead of:

Numbers.Dequeue();

you'll have to use:

int number;
Numbers.TryDequeue(out number);

this returns false in case the queue is empty.

Also, Microsoft added the following thread-safe collections:
  • System.Collections.Concurrent.ConcurrentBag
  • System.Collections.Concurrent.ConcurrentDictionary
  • System.Collections.Concurrent.ConcurrentQueue
  • System.Collections.Concurrent.ConcurrentStack
Have fun and no more thread unsafe code :)