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.