Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContainsKey Thread Safe

In the following code:

public class StringCache
{
    private readonly object lockobj = new object();

    private readonly Dictionary<int, string> cache = new Dictionary<int, string>();

    public string GetMemberInfo(int key)
    {
        if (cache.ContainsKey(key))
            return cache[key];
        lock (lockobj)
        {
            if (!cache.ContainsKey(key))
                cache[key] = GetString(key);
        }
        return cache[key];
    }

    private static string GetString(int key)
    {
        return "Not Important";
    }
}

1) Is ContainsKey thread safe? IOW, what happens if that method is executing when another thread is adding something to the dictionary? 2) For the first return cache[key], is there any chance that it could return a garbled value?

TIA,

MB

like image 857
MBeckius Avatar asked Apr 02 '09 17:04

MBeckius


2 Answers

No, ContainsKey is not thread-safe if you're writing values while you're trying to read.

Yes, there is a chance you could get back invalid results -- but you'll probably start seeing exceptions first.

Take a look at the ReaderWriterLockSlim for locking in situations like this -- it's built to do this kind of stuff.

like image 197
jsw Avatar answered Oct 28 '22 06:10

jsw


The inherent thread safety of ContainsKey doesn't matter, since there is no synchronization between ContainsKey & cache[key].

For example:

if (cache.ContainsKey(key))
   // Switch to another thread, which deletes the key.
   return cache[key];

MSDN is pretty clear on this point:

To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

For more info, JaredPar posted a great blog entry at http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx on thread-safe collections.

like image 38
Michael Avatar answered Oct 28 '22 08:10

Michael