When Iterating Over ConcurrentDictionary and only reading, is ConcurrentDictionary locked? When Iterating Over ConcurrentDictionary and only reading, is ConcurrentDictionary locked? multithreading multithreading

When Iterating Over ConcurrentDictionary and only reading, is ConcurrentDictionary locked?


This is how ConcurrentDictionary.GetEnumerator Is implemented:

/// <remarks>/// The enumerator returned from the dictionary is safe to use concurrently with/// reads and writes to the dictionary, however it does not represent a moment-in-time /// snapshot of the dictionary. The contents exposed through the enumerator may contain /// modifications made to the dictionary after <see cref="GetEnumerator"/> was called./// </remarks>public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator(){    Node[] buckets = m_tables.m_buckets;    for (int i = 0; i < buckets.Length; i++)    {        // The Volatile.Read ensures that the load of the fields of 'current'        // doesn't move before the load from buckets[i].        Node current = Volatile.Read<Node>(ref buckets[i]);        while (current != null)        {            yield return new KeyValuePair<TKey, TValue>(current.m_key, current.m_value);            current = current.m_next;        }    }}

As you see, the iteration is lock free, and simply yields a immutable struct (KeyValuePair) which is returned to the caller for each iteration. That is why it cant guarantee a snapshot-in-time of the ConcurrentDictionary

This will definitely not have a performance effect on adding/updating new values while iterating, but it simply cant guarantee that your admin will see the most updated snapshot of the dictionary.

  1. You can browse the rest of the source code yourself viahttp://sourceof.net
  2. And you can also check out Inside the Concurrent Collections:ConcurrentDictionary by Simon Cooper.
  3. Are all of the new concurrent collections lock-free?


This is what documentation is saying:

The enumerator returned from the dictionary is safe to use concurrently with reads and writes to the dictionary, however it does not represent a moment-in-time snapshot of the dictionary. The contents exposed through the enumerator may contain modifications made to the dictionary after GetEnumerator was called.

http://msdn.microsoft.com/en-us/library/dd287131(v=vs.110).aspx

So, if you want "snapshot" behavior, you will have to make a copy of the Keys collection and iterate over the copy, otherwise you will iterate over mutable thread safe collection.