SynchronizationLockException em Monitor.Exit ao usar aguardar

Estou criando um pedaço de código que obtém uma página da Web de um sistema legado que temos. Para evitar consultas excessivas, estou armazenando em cache o URL obtido. estou usandoMonitor.Enter, Monitor.Exit e verificação dupla para evitar que a solicitação seja emitida duas vezes, mas ao liberar o bloqueio comMonitor.Exit, Estou recebendo esta exceção:

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.<OpenFeature>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.<GetSupportFor>d__15.MoveNext() in c:\Users\me\Documents\Visual Studio 2013\Projects\MyApp\MyApp\Data\ExProvider.cs:line 71
  InnerException: 

A linha 56 é aMonitor.Exit. Este é o código que executa a operação:

private async Task<Stream> OpenReport(String report)
{
    var file = _directory.GetFiles(report+ ".html");
    if (file != null && 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);
        }
    }
}

Então, qual é o problema comawait eMonitor? É porque não é o mesmo segmento quandoMonitor.Enter do que quandoMonitor.Exit?

questionAnswers(3)

yourAnswerToTheQuestion