Throw a NullReferenceException while calling the set_item method of a Dictionary object in a multi-threading scenario

Solution 1:

As the exception occurs internally in the Dictionary code, it means that you are accessing the same Dictionary instance from more than one thread at the same time.

You need to synchronise the code in the GetInstance method so that only one thread at a time accesses the Dictionary.

Edit:
Lock around the accesses separately, so that you aren't inside a lock while doing the (supposedly) time consuming loading:

private static object _sync = new object();

public static object GetInstance(string key) {
   object instance = null;
   bool found;
   lock (_sync) {
      found = Instances.TryGetValue(key, out instance);
   }
   if (!found) {
      instance = LoadInstance(key);
      lock (_sync) {
         object current;
         if (Instances.TryGetValue(key, out current)) {
            // some other thread already loaded the object, so we use that instead
            instance = current;
         } else {
            Instances[key] = instance;
         }
      }
   }
   return instance;
}

Solution 2:

As of .Net 4 you have ConcurrentDictionary which is a thread-safe dictionary, no more need for "manual" synchronization.

Solution 3:

To quote http://msdn.microsoft.com/en-us/library/xfhwa508.aspx (emphasis added by me):

"Thread Safety

Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

A Dictionary<(Of <(TKey, TValue>)>) can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization."

Solution 4:

I think your Instances Dictionary is not null. Your exception is from inside the Insert method - meaning that there is a Dictionary object at runtime (Also, as you've said, you have already had TryGetValue before, on the same reference) Could it be that your key is null?

EDIT

Just checked it - TryGetValue throws ArgumentNullException when it receives a null key, and so does insert with a null key. But what class are you using in your example? I used the generic IDictionary<string, string>, but I see you are using a non generic one. Is it a class you have inherited from DictionaryBase or maybe HashTable?