title: Hierarchical locking strategy of entries in a ConcurrentDictionary and the dictionary itself in C#
body: <p>I'm forced to use a concurrent dictionary in my code, where the 'key' is a object and the 'value' is an int that represents a unique connection parameter to said object provided by a third party library. The connection parameter is stored, as when an event is thrown via the third party library, the unique key is one of the event arguments with which we can find the correct object to process further code on.</p>
  
  <p>The issue I have is as follows:</p>
  
  <ul>
  <li><p>Occasionally, the concurrent dictionary needs to be updated with a refreshed list of objects that require processing.</p></li>
  <li><p>The individual objects require a lock during the processing, as the thrown events must be performed sequentially and not in parallel. (This has become a recent requirement as we're seeing that the tasks are sometimes being processes in parallel on different threads and getting an OptimisticConcurrencyException when saving to the database.)</p></li>
  </ul>
  
  <p>Applying a lock to the individual objects within the dictionary is not a problem, but a new issue arises when I try to remove an object from the dictionary which is currently locked whilst refreshing the list.</p>
  
  <p>I've tried to write a small console app that executes the problematic steps sequentially, the 'Monitor.Exit(key);' line throws the exception 'Object synchronization method was called from an unsynchronized block of code.'</p>
  
  <pre><code>class Program
  {
      static ConcurrentDictionary&lt;object, int&gt; _handles = new ConcurrentDictionary&lt;object, int&gt;();
  
      static void Main(string[] args)
      {
          object lockableKey = 'key';
  
          _handles.AddOrUpdate(lockableKey, 10, (oldkey, oldvalue) =&gt; 10);
          var key = _handles.Keys.FirstOrDefault(h =&gt; h == lockableKey);
  
          Console.WriteLine("key found, beginning to lock");
          Monitor.Enter(key);
          Console.WriteLine("key locked");
  
          ////Console.WriteLine("applying outer lock, hoping for code to stop executing");
          ////Monitor.Enter(_handles);
  
          Console.WriteLine("Removing key from dictionary");
          int dummy;
          _handles.TryRemove(lockableKey, out dummy);
  
          Console.WriteLine("Removing lock from object removed from dictionary");
          Monitor.Exit(key);
      }
  </code></pre>
  
  <p>So the question is, is there a way to apply a lock to the outer dictionary that acts like a master lock and waits for all child locks on objects within the dictionary to finish executing before refreshing the dictionary and continuing to process the incoming events?</p>