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
ConcurrentDictionary
do I still need to use lock
on it or will it handle everything by itself.ConcurrentDictionary
, I have to use lock
on it directly or again I have to lock the SyncRoot
object for itThanks in advance!
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.
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.
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<,>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With