markmnl
markmnl

Reputation: 11426

Is accessing the Dictionary<TKey, TValue> Keys property thread safe?

For example can I go:

string[] keys = new string[items.Count];
items.Keys.CopyTo(keys);

Where items is a:

Dictionary<string, MyObject>

instance that could be being modified by another thread? (Its not clear to me if when accessing the Keys property the inner workings of Dictionary iterates the collection - in which case I know it would not be thread safe).

Update: I realise my above example is not thread safe becuase the size of the Dictonary could change between the lines. however what about:

Dictionary<string, MyObject> keys = items.Keys;
string[] copyOfKeys = new string[keys.Count];
keys.Keys.CopyTo(copyOfKeys );

Upvotes: 2

Views: 987

Answers (2)

usr
usr

Reputation: 171178

If the dictionary is being mutated on another thread it is not safe to do this. The first thing that comes to mind is that the dictionary might resize its internal buffer which surely does not play well with concurrent iteration.

If you aren't changing the keys and are only writing values this should be safe in practice.

Anyway, I wouldn't put such code into production because the risk is too high. What if some .NET patch changes the internals of Dictionary and suddenly you have a bug. There are other concerns as well.

I recommend you use ConcurrentDictionary or some other safe strategy. Why gamble with the correctness of your code?

Upvotes: 1

Daniel Mann
Daniel Mann

Reputation: 59020

No, Dictionary is not thread-safe. If you need thread safety and you're using .NET 4 or higher, you should use a ConcurrentDictionary.

From MSDN:

A Dictionary can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

Upvotes: 3

Related Questions