Interlocked.Increment on dictionary value

It is actually much easier. specially if you are not sure if the key is created or not.

The below, will increment the value by one if it exists and create it with a default value of 1 if it doesn't. Concurrents namespace contains almost everything you will ever need to build threadsafe objects. I don't generally like the use of locks as it serializes access to the object (Why are we doing multi-threading if we will do it in serial?)

ConcurrentDictionary<string, int> dataStore = new ConcurrentDictionary<string, int>();

public int Increment(string key)
{
    return dataStore.AddOrUpdate(key, 1, (k, v) => Interlocked.Increment(ref v));
}

Your main reason to use Interlocked is performance. If you're not having performance issues then your code will be understandable to more people, and easier to write and read, if you simply use a lock.

If you absolutely must use Interlocked, then you can't do it with a dictionary in the way you've tried to. Interlocked operations are atomic, often at the CPU level, and they require a fixed location in memory on which to operate. The property accessors on a dictionary don't provide this.

If you still wanted to use dictionaries, there are two methods that spring to mind:

Store your counts in an array

You'd store your count values in an array. Each cell is fixed in memory and can therefore be used by Interlocked. You dictionary, rather than storing the count, would store the index in this array at which the count was stored. Of course, you would write this all into a class such that these implementation details where hidden.

Store "count objects" in the dictionary

Each item in the dictionary would be an instance of a class that holds the count. Internally to the class, there would be a private int that could be used by Interlocked. Your class would provide Increment and Decrement methods, and a read-only Count property, to allow this to be used in a similar way.

edit

Use A Semaphore

Actually, one other thing you could look into is using a Semaphore. They're pretty much designed for this. By having each cell in the Dictionary be a Semaphore rather than a count, you can achieve a very similar thing in a threadsafe way. You would do dictionary[key].WaitOne(0), which would return true if it succeeded, and false if not. If it did return true, then that Semaphore's count has already been incremented and you just call Dictionary[hey].Release() again later.


Store a mutable heap object in the dictionary:

ConcurrentDictionary<..., StrongBox<int>> dict = ...;
Interlocked.Increment(ref dict[...].Value);

StrongBox.Value is a mutable field.