YMC
YMC

Reputation: 5452

Is not checking key existence in a static dictionary thread-safe? Resharper thinks it's not

Resharper suggests wrapping return dic.Contains("v1"); in a lock statement saying "the field is sometimes used inside synchronized block and sometimes used without synchronization":

public class MyClass
{
    private static Dictionary<string, string> _dic = new Dictionary<string, string>();

    protected bool V1Exist()
    {
        return dic.Contains("v1");            
    }
}

However I do not see why lock is needed in the example. It looks safe-thread to me. Please advise

Upvotes: 1

Views: 202

Answers (1)

Evk
Evk

Reputation: 101443

It's known that dictionary is not thread-safe, so you should synchronize both writes and reads. But if you want specific example of what can go wrong - consider this small application:

static void Main(string[] args) {
    var dict = new Dictionary<int, int>();
    dict.Add(0, 0);
    new Thread(() => {
        for (int i = 1; i < int.MaxValue; i++) {
            lock (dict) {
                dict.Add(i, i);
                dict.Remove(i);
            }
        }
    }).Start();
    new Thread(() => {
        while (true) {
            if (!dict.ContainsKey(0))
                throw new Exception("cannot happen?");
        }
    }).Start();
    Console.ReadKey();
}

We create dictionary with one entry with key 0, then we run two threads. First thread constantly adds and removes keys to the dictionary, but note it does NOT remove item with key 0. Item with key 0 is always present.

Second threads constantly checks if there is item with key 0 and throws exception if it does not. You might think that this can never happen, because we never remove item with key 0, but that is not true. If you will run this application it will throw "cannot happen?" exception almost immediately. If you add lock around ContainsKey - this will never happen.

So in short, things might go horribly wrong if you are not synchronizing access to not thread safe structures properly, even reads. And you might not even notice that, and will have VERY hard time debugging such issues, because application might behave like all is fine.

Upvotes: 2

Related Questions