title: ExecutionContext does not flow up the call stack from async methods
body: <p>Consider the following code:</p>
  
  <pre class="lang-cs prettyprint-override"><code>private static async Task Main(string[] args)
  {
      await SetValueInAsyncMethod();
      PrintValue();
  
      await SetValueInNonAsyncMethod();
      PrintValue();
  }
  
  private static readonly AsyncLocal&lt;int&gt; asyncLocal = new AsyncLocal&lt;int&gt;();
  
  private static void PrintValue([CallerMemberName] string callingMemberName = "")
  {
      Console.WriteLine($"{callingMemberName}: {asyncLocal.Value}");
  }
  
  private static async Task SetValueInAsyncMethod()
  {
      asyncLocal.Value = 1;
      PrintValue();
  
      await Task.CompletedTask;
  }
  
  private static Task SetValueInNonAsyncMethod()
  {
      asyncLocal.Value = 2;
      PrintValue();
  
      return Task.CompletedTask;
  }
  </code></pre>
  
  <p>If you run this code inside a .NET 4.7.2 console application, you will get the following output:</p>
  
  <pre><code>SetValueInAsyncMethod: 1
  Main: 0
  SetValueInNonAsyncMethod: 2
  Main: 2
  </code></pre>
  
  <p>I do understand that the differences in the output arise from the fact that <code>SetValueInAsyncMethod</code> is not really a method, but a state machine executed by <code>AsyncTaskMethodBuilder</code> which captures <code>ExecutionContext</code> internally and <code>SetValueInNonAsyncMethod</code> is just a regular method. </p>
  
  <p>But even with this understanding in mind I still have some questions:</p>
  
  <ol>
  <li>Is this a bug / missing feature or an intentional design decision?</li>
  <li>Do I need to worry about this behavior while writing code that depends on <code>AsyncLocal</code>? Say, I want to write my <code>TransactionScope</code>-wannabe that flows some ambient data though await points. Is <code>AsyncLocal</code> enough here?</li>
  <li>Are there any other alternatives to <code>AsyncLocal</code> and <code>CallContext.LogicalGetData</code> / <code>CallContext.LogicalSetData</code> in .NET when it comes down to preserving values throughout the "logical code flow"?</li>
  </ol>