KDecker KDecker - 3 months ago 9
C# Question

Multithreaded acess to non-threadsafe values within a System.Collection.Concurrent?

If I am using a collection from the

System.Collection.Concurrent
namespace, such as
ConcurrentDictionary<K, V>
, with a key and/or value type that is not threadsafe, for instance
ConcurrentDictionary<int, Dictionary<int, int>>
What are the possible issues faced?

I assume that I can do any operation that I please on the
ConcurrentDictionary
itself, but what if I create a
System.Collections.Generic.List<T>
of the
Dictionary<int, int>
from that
ConcurrentDictionary
and modify it?

Here I create the list with LINQ in "one line" though I assume that once the
ToList
is executed I am out of the safety of the
ConcurrentDictionary
lock
?

ConcurrentDictionary<int, Dictionary<int, int>> conDict = ...;
conDict.Select(x => x.Value).ToList().ForEach(x => x.Add(1, 2));


If that is safe or unsafe I then assume this is too

ConcurrentDictionary<int, Dictionary<int, int>> conDict = ...;
var regDictList = conDict.Select(x => x.Value).ToList();
regDictList.ForEach(x => x.Add(1, 2));

Answer

Well, the ConcurrentDictionary is by itself self for access from multiple threads (TryAdd, TryGetValue, Etc...).

It's important to understand that it's not the objects contained by the ConcurrentDictionary that are thread-safe but the ConcurrentDictionary itself.


If you access a specific value contained by the dictionary from multiple threads than you have to make sure it is thread-safe as well.

Since the result from:

conDict.Select(x => x.Value)

is:

IEnumerable<Dictionary<int, int>>

and it no longer has anything to do with the ConcurrentDictionary - a List<Dictionary<int, int>> retrieved by:

conDict.Select(x => x.Value).ToList()

is of course NOT thread-safe

Comments