title: Can't safely lock a value of a ConcurrentDictionary
body: <p>I'm having trouble locking on an item within a Collection - specifically a ConcurrentDictionary.</p>
  
  <p>I need to accept a message, look up that message within the Dictionary and then run a lengthy scan on that. As the program takes a lot of memory, after the scan the objects return <strong>true</strong> if they think its a good time to delete it (which I do by removing it from the Dictionary). However, another thread could come at a similar time and try to access that same object right after the delete. This is my first attempt:</p>
  
  <pre><code>string dictionaryKey = myMessage.someValue;
  
  DictionaryObject currentObject = myConcurrentDictionary.GetOrAdd(dictionaryKey, new DictionaryObject());
  // we can be interrupted here
  lock (currentObject)
  {
      //KeyNotFoundException is possible on line below
      if (myConcurrentDictionary[dictonaryKey].scan(myMessage)) // Scans the message - returns true if the object says its OK to remove it from the dictionary
      {
        DictionaryObject temp;                      //   It's OK to delete it
        if (!queuedMessages.TryRemove(ric, out temp))   // Did delete work?
         throw new Exception("Was unable to delete a DictionaryObject that just reported it was ok to delete it");
      }
  }
  </code></pre>
  
  <p>However, the above doesn't work - it's possible for one thread to remove an object from the Dictionary right before another is going to attempt to access that object within the Dictionary. After reading that <a href="http://www.albahari.com/threading/part2.aspx#_Locking" rel="nofollow">lock is shorthand for Monitor.Enter and Monitor.Exit</a>, I tried this:</p>
  
  <pre><code>string dictionaryKey = myMessage.someValue;
  Monitor.Enter(GetDictionaryLocker);
  DictionaryObject currentObject = myConcurrentDictionary.GetOrAdd(dictionaryKey, new DictionaryObject());
  // we can be interrupted here
  lock (currentObject)
  {
      Monitor.Exit(GetDictionaryLocker);
      //KeyNotFoundException is still possible on line below
      if (myConcurrentDictionary[dictonaryKey].scan(myMessage)) // Scans the message - returns true if the object says its OK to remove it from the dictionary
      {
        DictionaryObject temp;                   //   It's OK to delete it
        if (!queuedMessages.TryRemove(ric, out temp))   // Did delete work?
         throw new Exception("Was unable to delete a DictionaryObject that just reported it was ok to delete it");
      }
  }
  </code></pre>
  
  <p>Both ways can result in a <strong>KeyNotFoundException</strong> when trying to look the object up within the Dictionary.</p>
  
  <p>Does anyone know how I could find the object I want to lock and then lock it without being interrupted? Sorry - I'm new at concurrency and feel thoroughly confused!</p>
  
  <p>Thanks,</p>
  
  <p>Frederik</p>