How to add item to dictionary "Parallel loop safe"

Amaranth picture Amaranth · Apr 1, 2014 · Viewed 10.6k times · Source

I have a Parallel.ForEach loop doing some treatment. But the first operation is to add a value in the dictionary if the key is not contained. I get an error when adding it, it says that the key is already in the dictionary. I guess that the key was added by a parallel process after the .Contains check of this thread, but before the add. Other than placing that line in a try-catch, is there another simple solution I can use to prevent that error?

Parallel.ForEach(branchFixes, b =>
{
  Parallel.ForEach(b.Value, t =>
  {
    var team = t.Key;
    if (!resultTeamDict.ContainsKey(team))
    {
      resultTeamDict.Add(team, new Dictionary<FixItem, Dictionary<BranchInfo, bool>>());
    }
  });
});

Answer

Jon Skeet picture Jon Skeet · Apr 1, 2014

Even aside from your race condition, Dictionary<,> isn't thread-safe. You should be using ConcurrentDictionary<,> and in this case probably the AddOrUpdate method to perform the modification atomically. (I assume that you want to add a value to the "nested" dictionary too. Otherwise, consider TryAdd.)