Correct way to lock the dictionary object
So can anybody please suggest me which is the best way to lock the dictionary?
if you want to continue using the classic Dictionary<,>
AFAK you have to look to ICollection
interface implemented by Dictionary and use the property ICollection.SyncRoot
which by definition
MSDN
Gets an object that can be used to synchronize access to the ICollection.
So to achieve this you can do something like this
If I use ConcurrentDictionary do I still need to use lock on it or will it handle everything by itself.
From MSDN
ConcurrentDictionary is designed for multithreaded scenarios. You do not have to use locks in your code to add or remove items from the collection. However, it is always possible for one thread to retrieve a value, and another thread to immediately update the collection by giving the same key a new value.
If I have to use lock on ConcurrentDictionary, I have to use lock on it directly or again I have to lock the SyncRoot object for it
Yes you have to use lock
on SyncRoot
if you want to do Atomic methods execution when you use GetOrAdd
or AddOrUpdate
methods
With Dictionary<,>
you have to lock both reading and writing. So both
lock( ConnectionList ) {
ConnectionList.Add( key, res );
}
and
lock( ConnectionList ) {
res = ConnectionList[ key ];
}
and
lock( ConnectionList ) {
int cnt = ConnectionList.Count;
}
and
lock( ConnectionList ) {
ConnectionList.Clear();
}
and
lock( ConnectionList ) {
foreach ( var kv in ConnectionList ) {
// Do things
}
}
and so on :-)
With ConcurrentDictionary<,>
you don't need any locking, but note that the syntax is a little different than the one of the Dictionary<,>
- So can anybody please suggest me which is the best way to lock the dictionary
You can use it's SyncRoot
or create a private object that you lock when accessing the dictionary object, e.g.
private static object _sybcRoot = new object();
public static void Add( string key, string res)
lock( _sybcRoot ) {
ConnectionList.Add( key, res );
}
}
You have to use the same lock object to guard the access to the same resource. Otherwise threads may "think" the resource is free, whereas in reality it is used by the other thread which just happen to lock it on the other object's sync root.
- If I use ConcurrentDictionary do I still need to use lock on it or will it handle everything by itself.
No, there is no need for locking when using any Concurrent*
collection. It is thread-safe by design, but this syntax is slightly different. Concurrent*
collections use lockless approach, which is better in a situations when you don't have many threads competing for access (optimistic concurrency)
- If I have to use lock on ConcurrentDictionary, I have to use lock on it directly or again I have to lock the SyncRoot object for it