Updating List in ConcurrentDictionary

Firstly, there's no need to do ContainsKey() and TryGetValue().

You should just do this:

IList<string> templist;

if (list1.TryGetValue(key, out templist))
    templist.Add("helloworld");

In fact your code as written has a race condition.

Inbetween one thread calling ContainsKey() and TryGetValue() a different thread may have removed the item with that key. Then TryGetValue() will return tempList as null, and then you'll get a null reference exception when you call tempList.Add().

Secondly, yes: There's another possible threading issue here. You don't know that the IList<string> stored inside the dictionary is threadsafe.

Therefore calling tempList.Add() is not guaranteed to be safe.

You could use ConcurrentQueue<string> instead of IList<string>. This is probably going to be the most robust solution.

Note that simply locking access to the IList<string> wouldn't be sufficient.

This is no good:

if (list1.TryGetValue(key, out templist))
{
    lock (locker)
    {
        templist.Add("helloworld");
    }
}

unless you also use the same lock everywhere else that the IList may be accessed. This is not easy to achieve, hence it's better to either use a ConcurrentQueue<> or add locking to this class and change the architecture so that no other threads have access to the underlying IList.


Operations on a thread-safe dictionary are thread-safe by key, so to say. So as long as you access your values (in this case an IList<T>) only from one thread, you're good to go.

The ConcurrentDictionary does not prevent two threads at the same time to access the value beloning to one key.


The ConcurrentDictionary has no effect on whether you can apply changes to value objects in a thread-safe manner or not. That is the reponsiblity of the value object (the IList-implementation in your case).

Looking at the answers of No ConcurrentList<T> in .Net 4.0? there are some good reasons why there is no ConcurrentList implementation in .net.

Basically you have to take care of thread-safe changes yourself. The most simple way is to use the lock operator. E.g.

lock (templist)
{
   templist.Add("hello world");
}

Another way is to use the ConcurrentBag in the .net Framework. But this way is only useful for you, if you do not rely on the IList interface and the ordering of items.

Tags:

C#

Concurrency