Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to lock the dictionary object

Tags:

In my code I have a static dictionary object

private static IDictionary< ConnKey, DbConnection > ConnectionList = new Dictionary< ConnKey, DbConnection >( );

which is throwing this error

System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
  at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)

I searched and found that this occurs because multiple threads try to access dictionary, but I do have lock on dictionary

lock( ConnectionList ) {
   ConnectionList.Add( key, res );
}

Then I searched more and found that lock on dictionary doesn't prevent all the operations on it so I should be using lock on SyncRoot object of it like this to achieve what I want

lock( ((IDictionary)ConnectionList).SyncRoot) {

But then I searched that using SyncRoot is not a good practice

On further search I found there is a ConcurrentDictionary for this purpose

  1. So can anybody please suggest me which is the best way to lock the dictionary
  2. If I use ConcurrentDictionary do I still need to use lock on it or will it handle everything by itself.
  3. 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

Thanks in advance!

like image 939
Pawan Nogariya Avatar asked Apr 10 '15 09:04

Pawan Nogariya


People also ask

Does ConcurrentDictionary need lock?

ConcurrentDictionary<TKey,TValue> 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.

What is concurrent dictionary?

adjective. occurring or existing simultaneously or side by side: concurrent attacks by land, sea, and air. acting in conjunction; cooperating: the concurrent efforts of several legislators to pass the new law. having equal authority or jurisdiction: two concurrent courts of law.


1 Answers

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<,>

like image 76
xanatos Avatar answered Oct 07 '22 01:10

xanatos