Why Dictionary indexer is not thread safe and how to make it

If you read my blog about why ++ operator is not thread safe you’ll know that a one line C# code doesn’t mean it is thread safe and Dictionary indexer is no exception.

Recently someone came to me and ask me: I have a static dictionary in a web application, do you think it is possible that two request try to add the same element at the same time and fails. The answer is obviously yes. Let’s see how this happens.

We will buil a sample code that wil prove the point. Of course this is not real production code but it will be easy to expose the problem. First we need a dictionary:

Let say, somewhere in your code you do something like this:

This single line of code looks better than:

but it is not.

In both cases you can encounter race condition. Take a look at how the indexer is implemented:

Ok the setter uses a private Insert method. This is where it gets worst:

That’s alot of code to add an item to the dictionary. As we saw earlier, there’s a lot of “not thread safe” code in there.

The easiest way to resolve this problem is to put a lock around the dictionary operations. First we need an object to lock on. It’s always a good practice to have a separate object to lock on even though it is possible to lock the dictionary itself. We can create that object ourself but every collection already have a SyncLock object but it’s not visible because it’s explicitly implemented. To access it we need to cast the dictionary to an ICollection.

With this new implementation, our code should run without any problem.

One thought on “Why Dictionary indexer is not thread safe and how to make it

  1. Thank you very much for these explanations. Using Synclock instead of object itself seems to have partially solved my race conditions problems.
    Unfortunately it seems that i still have strange behaviors, especially while making a “Clear” of Dictionary.

Leave a Reply