9

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});
7
  • 6
    Yes, you're using a type which is documented as not being thread safe, from multiple threads without anything to make that safe. Commented Sep 29, 2016 at 11:56
  • I think I could probably guess, but why don't you tell us what the problem is rather than making us guess? Commented Sep 29, 2016 at 11:57
  • what's the error ? Commented Sep 29, 2016 at 11:57
  • thats the problem - studio doesnt give a error - it just breaks Commented Sep 29, 2016 at 11:59
  • 1
    Define "breaks" Commented Sep 29, 2016 at 12:03

2 Answers 2

18

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});
Sign up to request clarification or add additional context in comments.

3 Comments

@TimSchmelter Well done to mention it I forgot to add it. It was a time constraint
in this case added = false and Server.Values = null. Thats the most of "error" i get
you have to initiliaze it first I updated my answer
8

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.

8 Comments

why reinvinting the weel if you have concurrentDictionary :p
this is worth to be mentioned in case he can't change the type +1
I'd prefer a variable ServerDictionaryLock, then it's clear what you are locking with it.
@TimSchmelter -- well, I've tried to make it as generic as possible, but I see your point.
@rory.ap: the problem with the _lock object is that people implement it in that way and it suggests to use one lock-variable per class. That will lock the whole instance and on any action that uses it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.