title: How to combine asynchrony with locking?
body: <p>As the famous <a href="https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html" rel="noreferrer">blog post from Stephen Cleary</a> dictates, one should never try to run async code synchronously (e.g. via <code>Task.RunSynchronously()</code> or accessing <code>Task.Result</code>). On the other hand, you can't use async/await inside <code>lock</code> statement.</p>
  <p>My use case is ASP.NET Core app, which uses <code>IMemoryCache</code> to cache some data. Now when the data is not available, (e.g. cache is dropped) I have to repopulate it, and that should be guarded with <code>lock</code>.</p>
  <pre><code>public TItem Get&lt;TItem&gt;(object key, Func&lt;TItem&gt; factory)
  {
      if (!_memoryCache.TryGetValue(key, out TItem value))
      {
          lock (_locker)
          {
              if (!_memoryCache.TryGetValue(key, out value))
              {
                  value = factory();
                  Set(key, value);
              }
          }
      }
      return value;
  }
  </code></pre>
  <p>In this example, the factory function can not be async! What should be done if it has to be async?</p>