Home > Mobile >  Dictionary of ManualResetEvent - ThreadSafety
Dictionary of ManualResetEvent - ThreadSafety

Time:02-16

I'm synchronizing some threads using a dictionary of ManualResetEvents. It looks something like this. My question is, Is it thread-safe to call a getter/indexer of the dictionary like this? Should I call the getter from the context of a lock and store the value in a local variable?

Enum Type

enum RecvType
{
    Type1,
    Type2
    //etc...
}

Dictionary of ManualResetEvents

Dictionary<RecvType, ManualResetEvent> recvSync;

Wait operation

 void WaitForRecv(RecvType recvType, int timeout = 10000)
 {
    if (!recvSync[recvType].WaitOne(timeout))
    {
        throw new TimeoutException();
    }
        
    // do stuff
 }

EventHandler (called from another thread)

void RecvDone(object sender, RecvType recvType)
{
    recvSync[recvType].Set();
}

EDIT - clarify dictionary population

Dictionary Instanciation

public MyClass()
{
    recvSync = new Dictionary<RecvType, ManualResetEvent>();
    // populate dictionary (not modified after here)
    socketWrapper.RecvDone  = RecvDone;
}

CodePudding user response:

According to the documentation:

A Dictionary<TKey,TValue> can support multiple readers concurrently, as long as the collection is not modified.

So your pattern of usage is OK, regarding thread-safety. The behavior of a "frozen" Dictionary<K,V> when multiple threads are reading it, is well defined.

You could consider communicating your intentions more clearly by using an ImmutableDictionary<K,V> instead of a normal Dictionary<K,V>, but that clarity would come with a cost: Finding an element in an ImmutableDictionary<K,V> is ~10 times slower.

  • Related