Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a new item in dictionary from multiple threads

I have a problem adding a new item to a Static dictionary while using it from multiple threads. Any ideas where I'm doing it wrong? Initializing the dictionary:

public static class Server
{
    public static volatile Dictionary<int, List<SomeClass>> Values;
}

Trying to add an item:

Server.Values.Add(someInt, new List<SomeClass> { elements});
like image 981
vlad Avatar asked Dec 03 '22 14:12

vlad


2 Answers

As explained by Jon Skeet you are using an object which is not guaranteed to be thread safe

try using ConcurrentDictionary which is designed for Concurrency Scenario With Many threads

public static class Server
{
    public static  ConcurrentDictionary<int, List<SomeClass>> Values =
                      new ConcurrentDictionary<int, List<SomeClass>>(); 
}

Here how to use it

bool added = Server.Values.TryAdd(someInt, new List<SomeClass> { elements});
like image 108
BRAHIM Kamel Avatar answered Dec 29 '22 20:12

BRAHIM Kamel


In general, when working with resources that are shared between multiple threads, you need to use a synchronization mechanism, like lock() to make your code thread safe. Create a common object to use as the lock:

private object _lock = new object();

Then you surround any code which accesses your shared resource, like this:

lock(_lock)
{
    // perform operations on shared resource here.
}

It's important to note that you should have a different lock for every shared resource rather than one lock used for all resources. If you use your lock object with multiple resources, your code could be very inefficient. If one thread grabs the lock so it can use resource A, then other threads will have to wait for the lock to be released even if they want to access resource B which has nothing to do with the resource A. Therefore, it's better to have one lock object per resource and to name your lock objects so you know which resources they should be used with.

An alternative to this (as BRAHIM Kamel's answer shows) is to use a replacement, if available, for your shared resource which already has thread synchronization baked in, like ConcurrentDictionary. Though this may not be feasible in your case.

like image 30
rory.ap Avatar answered Dec 29 '22 19:12

rory.ap