2
votes

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.

This is what MSDN says.

I don't want to use ConcurrentDictionary if it is not necessary

I assume, if there is only one thread performing writer operations on Dictionary<T,K>, it is safe for other threads to perform simple reading operations(like TryGetValue not enumeration) at the same time without acquiring a lock, am I correct?

2

2 Answers

6
votes

I assume, if there is only one thread performing writer operations on Dictionary, it is safe for other threads to perform simple reading operations(like TryGetValue not enumeration) at the same time without acquiring a lock

No. Your assumption is wrong. It is safe only when no writers are modifying the dictionary not when you have a single writer.

ReaderWriterLockSlim is exactly designed to be used in this scenario. That said I'd just use ConcurrentDictionary instead of Re-inventing the wheel.

3
votes

The old System.Collections.Hashtable is safe for multiple-readers-single-writer scenarios, that is, any number of threads can read from the Hashtable, but at most one thread can modify it at the same time. (The writer thread can safely modify the Hashtable while the readers are reading from it).

The generic Dictionary<T,K> is not safe for such scenarios - use ConcurrentDictionary<T,K> instead.

Note that System.Collections.Hashtable and ConcurrentDictionary<T,K> use completely different implementation and provide different API. ConcurrentDictionary<T,K> fits well for such scenarios as lazy initialization and read-through cache. System.Collections.Hashtable is more performant as it is a kind of lock-free data structure, while ConcurrentDictionary<T,K> uses thread synchronization marshaled to Windows API.