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.