title: Task.Yield() in library needs ConfigureWait(false)
body: <p>It's <a href="https://msdn.microsoft.com/en-us/magazine/jj991977.aspx" rel="noreferrer">recommended that one use <code>ConfigureAwait(false)</code> whenever when you can</a>, especially in libraries because it can help avoid deadlocks and improve performance.</p>
  
  <p>I have written a library that makes heavy use of async (accesses web services for a DB).  The users of the library were getting a deadlock and after much painful debugging and tinkering I tracked it down to the single use of <code>await Task.Yield()</code>. Everywhere else that I have an await, I use <code>.ConfigureAwait(false)</code>, however that is not supported on <code>Task.Yield()</code>.</p>
  
  <p>What is the recommended solution for situations where one needs the equivalent of <code>Task.Yield().ConfigureAwait(false)</code>?</p>
  
  <p>I've read about how there was a <a href="https://stackoverflow.com/q/15363413/268898"><code>SwitchTo</code> method that was removed</a>. I can see why that could be dangerous, but why is there no equivalent of <code>Task.Yield().ConfigureAwait(false)</code>?</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>To provide further context for my question, here is some code.  I am implementing an <a href="https://github.com/Adamantworks/Amazon.DynamoDB" rel="noreferrer">open source library</a> for accessing DynamoDB (a distributed database as a service from AWS) that supports async.  A number of operations return <code>IAsyncEnumerable&lt;T&gt;</code> as provided by the <a href="https://www.nuget.org/packages/Ix-Async/" rel="noreferrer">IX-Async library</a>.  That library doesn't provide a good way of generating async enumerables from data sources that provide rows in "chunks" i.e. each async request returns many items.  So I have my own generic type for this.  The library supports a read ahead option allowing the user to specify how much data should be requested ahead of when it is actually needed by a call to <code>MoveNext()</code>.</p>
  
  <p>Basically, how this works is that I make requests for chunks by calling <code>GetMore()</code> and passing along state between these.  I put those tasks in a <code>chunks</code> queue and dequeue them and turn them into actual results that I put in a separate queue.  The <code>NextChunk()</code> method is the issue here.  Depending on the value of <code>ReadAhead</code> I will keeping getting the next chunk as soon as the last one is done (All) or not until a value is needed but not available (None) or only get the next chunk beyond the values that are currently being used (Some).  Because of that, getting the next chunk should run in parallel/not block getting the next value. The enumerator code for this is:</p>
  
  <pre><code>private class ChunkedAsyncEnumerator&lt;TState, TResult&gt; : IAsyncEnumerator&lt;TResult&gt;
  {
      private readonly ChunkedAsyncEnumerable&lt;TState, TResult&gt; enumerable;
      private readonly ConcurrentQueue&lt;Task&lt;TState&gt;&gt; chunks = new ConcurrentQueue&lt;Task&lt;TState&gt;&gt;();
      private readonly Queue&lt;TResult&gt; results = new Queue&lt;TResult&gt;();
      private CancellationTokenSource cts = new CancellationTokenSource();
      private TState lastState;
      private TResult current;
      private bool complete; // whether we have reached the end
  
      public ChunkedAsyncEnumerator(ChunkedAsyncEnumerable&lt;TState, TResult&gt; enumerable, TState initialState)
      {
          this.enumerable = enumerable;
          lastState = initialState;
          if(enumerable.ReadAhead != ReadAhead.None)
              chunks.Enqueue(NextChunk(initialState));
      }
  
      private async Task&lt;TState&gt; NextChunk(TState state, CancellationToken? cancellationToken = null)
      {
          await Task.Yield(); // ** causes deadlock
          var nextState = await enumerable.GetMore(state, cancellationToken ?? cts.Token).ConfigureAwait(false);
          if(enumerable.ReadAhead == ReadAhead.All &amp;&amp; !enumerable.IsComplete(nextState))
              chunks.Enqueue(NextChunk(nextState)); // This is a read ahead, so it shouldn't be tied to our token
  
          return nextState;
      }
  
      public Task&lt;bool&gt; MoveNext(CancellationToken cancellationToken)
      {
          cancellationToken.ThrowIfCancellationRequested();
  
          if(results.Count &gt; 0)
          {
              current = results.Dequeue();
              return TaskConstants.True;
          }
          return complete ? TaskConstants.False : MoveNextAsync(cancellationToken);
      }
  
      private async Task&lt;bool&gt; MoveNextAsync(CancellationToken cancellationToken)
      {
          Task&lt;TState&gt; nextStateTask;
          if(chunks.TryDequeue(out nextStateTask))
              lastState = await nextStateTask.WithCancellation(cancellationToken).ConfigureAwait(false);
          else
              lastState = await NextChunk(lastState, cancellationToken).ConfigureAwait(false);
  
          complete = enumerable.IsComplete(lastState);
          foreach(var result in enumerable.GetResults(lastState))
              results.Enqueue(result);
  
          if(!complete &amp;&amp; enumerable.ReadAhead == ReadAhead.Some)
              chunks.Enqueue(NextChunk(lastState)); // This is a read ahead, so it shouldn't be tied to our token
  
          return await MoveNext(cancellationToken).ConfigureAwait(false);
      }
  
      public TResult Current { get { return current; } }
  
      // Dispose() implementation omitted
  }
  </code></pre>
  
  <p>I make no claim this code is perfect.  Sorry it is so long, wasn't sure how to simplify.  The important part is the <code>NextChunk</code> method and the call to <code>Task.Yield()</code>.  This functionality is used through a static construction method:</p>
  
  <pre><code>internal static class AsyncEnumerableEx
  {
      public static IAsyncEnumerable&lt;TResult&gt; GenerateChunked&lt;TState, TResult&gt;(
          TState initialState,
          Func&lt;TState, CancellationToken, Task&lt;TState&gt;&gt; getMore,
          Func&lt;TState, IEnumerable&lt;TResult&gt;&gt; getResults,
          Func&lt;TState, bool&gt; isComplete,
          ReadAhead readAhead = ReadAhead.None)
      { ... }
  }
  </code></pre>