Is it possible for a Dictionary in .Net to cause dead lock when reading and writing to it in parallel?

So your code is executing Dictionary.FindEntry. It’s not a deadlock – a deadlock happens when two threads block in a way which makes them wait for one another to release a resource, but in your case you’re getting two seemingly infinite loops. The threads aren’t locked.

Let’s take a look at this method in the reference source:

private int FindEntry(TKey key) {
    if( key == null) {
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
    }

    if (buckets != null) {
        int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
        for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
            if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
        }
    }
    return -1;
}

Take a look at the for loop. The increment part is i = entries[i].next, and guess what: entries is a field which is updated in the Resize method. next is a field of the inner Entry struct:

public int next;        // Index of next entry, -1 if last

If your code can’t exit the FindEntry method, the most probable cause would be you’ve managed to mess the entries in such a way that they produce an infinite sequence when you’re following the indexes pointed by the next field.

As for the Insert method, it has a very similar for loop:

for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)

As the Dictionary class is documented to be non-threadsafe, you’re in the realm of undefined behavior anyway.

Using a ConcurrentDictionary or a locking pattern such as a ReaderWriterLockSlim (Dictionary is thread-safe for concurrent reads only) or a plain old lock nicely solves the problem.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)