Incrementing a integer value in a concurrent dictionary

174 views Asked by At

I have a concurrent dictionary which is a class variable:

private readonly ConcurrentDictionary<Id, int> _tracker=
            new ConcurrentDictionary<Id, int>(Id.EqualityComparer);

I'm incrementing it in a method as follows:

_tracker[id]++;

Is this safe to do so if the _tracker will be accesed concurrently? Or should I be using the

_tracker.AddOrUpdate(id, 1, (id, count) => count+ 1);
2

There are 2 answers

6
Tim Schmelter On BEST ANSWER

_tracker[id]++ is not an atomic operation. You are calling the getter of the indexer method to retrieve the value in a thread safe way. Then you call the setter of the indexer in a thread safe way. Whatever happens in between is not thread safe. So another thread could modify that value before you set it. So better use AddOrUpdate which is thread safe (in your case, read Is AddOrUpdate thread safe in ConcurrentDictionary?).

So your code is basically:

int i = _tracker[id]; // thread safe
// not thread safe, the value in the dictionary could change here
_tracker[id] = i + 1; // thread safe
1
Jeeva Subburaj On

_tracker[id]++ may be inconsistent in multi-thread environment since it gets the value first and then updates it.

It's safe to use GetOrUpdate or Interlocked.Increment

Interlocked.Increment(ref _tracker[id]);