How to add an item to the Safe Parallel Loop dictionary

I have a Parallel.ForEach loop doing some cure. But the first operation is to add a value to 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 assume that the key was added by the parallel process after checking the .Contains of this stream, but before adding it. Besides putting this line in try-catch, is there another simple solution I can use to prevent this 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>>()); } }); }); 
+7
dictionary c # parallel.foreach
source share
3 answers

Even if you are unsure of your racial status, Dictionary<,> not thread safe. You should use ConcurrentDictionary<,> , and in this case, perhaps the AddOrUpdate method to perform the modification atomically, (I assume that you want to add the value to the "nested" dictionary too. Otherwise, consider TryAdd .)

+13
source share

You can use ConcurrentDictionary in .NET 4.5 and replace the ContainsKey and Add calls with the TryAdd method. See http://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx

+4
source share

This is an example of a textbook of the error β€œTime to check at the time of use”: between checking if the dictionary contains a key and calling Add , another thread might insert the element already, invalidating the Add background.

The solution is to use ConcurrentDictionary<T> or mutually exclude threads from updating the dictionary at the same time using a lock or other synchronization tool.

You might want to profile your code to see if it’s even worth it to turn off threads β€” the overhead can be very high in this case.

+2
source share

All Articles