title: SynchronizationLockException on Monitor.Exit when using await
body: <p>I am creating a piece of code that gets a webpage from a legacy system we have. In order to avoid excessive querying, I am caching the obtained URL. I am using <code>Monitor.Enter</code>, <code>Monitor.Exit</code> and double checking to avoid that request is issued twice, but when releasing the lock with <code>Monitor.Exit</code>, I am getting this exception:</p>
  
  <pre><code>System.Threading.SynchronizationLockException was caught
    HResult=-2146233064
    Message=Object synchronization method was called from an unsynchronized block of code.
    Source=MyApp
    StackTrace:
         at MyApp.Data.ExProvider.&lt;OpenFeature&gt;d__0.MoveNext() in c:\Users\me\Documents\Visual Studio 2013\Projects\MyApp\MyApp\Data\ExProvider.cs:line 56
      --- End of stack trace from previous location where exception was thrown ---
         at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
         at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
         at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
         at MyApp.Data.ExProvider.&lt;GetSupportFor&gt;d__15.MoveNext() in c:\Users\me\Documents\Visual Studio 2013\Projects\MyApp\MyApp\Data\ExProvider.cs:line 71
    InnerException: 
  </code></pre>
  
  <p>The line 56 is the <code>Monitor.Exit</code>. This is the code that performs the operation:</p>
  
  <pre><code>private async Task&lt;Stream&gt; OpenReport(String report)
  {
      var file = _directory.GetFiles(report+ ".html");
      if (file != null &amp;&amp; file.Any())
          return file[0].OpenRead();
      else
      {
          try
          {
              Monitor.Enter(_locker);
              FileInfo newFile = new FileInfo(Path.Combine(_directory.FullName, report + ".html"));
              if (!newFile.Exists) // Double check
              {
                  using (var target = newFile.OpenWrite())
                  {
                      WebRequest request = WebRequest.Create(BuildUrl(report));
                      var response = await request.GetResponseAsync();
                      using (var source = response.GetResponseStream())
                          source.CopyTo(target);
                  }
              }
              return newFile.OpenRead();
          }
          finally
          {
              Monitor.Exit(_locker);
          }
      }
  }
  </code></pre>
  
  <p>So what is the problem with <code>await</code> and <code>Monitor</code>? Is it because it is not the same thread when <code>Monitor.Enter</code> than when <code>Monitor.Exit</code>?</p>