title: Understanding async/await without threads
body: <p><a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx#BKMK_Threads" rel="noreferrer">According to MSDN</a>, <code>async</code> and <code>await</code> do not create new threads:</p>
  
  <blockquote>
    <p>The <code>async</code> and <code>await</code> keywords don't cause additional threads to be created.</p>
  </blockquote>
  
  <p>With this in mind, I'm having difficulty understanding control flow of some simple programs. My complete example is below. Note that it requires the <a href="http://msdn.microsoft.com/en-us/library/hh228603.aspx" rel="noreferrer">Dataflow library</a>, which you can install from NuGet.</p>
  
  <pre><code>using System;
  using System.Threading.Tasks.Dataflow;
  
  namespace TaskSandbox
  {
      class Program
      {
          static void Main(string[] args)
          {
              BufferBlock&lt;int&gt; bufferBlock = new BufferBlock&lt;int&gt;();
  
              Consume(bufferBlock);
              Produce(bufferBlock);
  
              Console.ReadLine();
          }
  
          static bool touched;
          static void Produce(ITargetBlock&lt;int&gt; target)
          {
              for (int i = 0; i &lt; 5; i++)
              {
                  Console.Error.WriteLine("Producing " + i);
                  target.Post(i);
                  Console.Error.WriteLine("Performing intensive computation");
                  touched = false;
                  for (int j = 0; j &lt; 100000000; j++)
                      ;
                  Console.Error.WriteLine("Finished intensive computation. Touched: " + touched);
              }
  
              target.Complete();
          }
  
          static async void Consume(ISourceBlock&lt;int&gt; source)
          {
              while (await source.OutputAvailableAsync())
              {
                  touched = true;
                  int received = source.Receive();
                  Console.Error.WriteLine("Received " + received);
              }
          }
      }
  }
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>Producing 0
  Performing intensive computation
  Received 0
  Finished intensive computation. Touched: True
  Producing 1
  Performing intensive computation
  Received 1
  Finished intensive computation. Touched: True
  Producing 2
  Performing intensive computation
  Received 2
  Finished intensive computation. Touched: False
  Producing 3
  Performing intensive computation
  Received 3
  Finished intensive computation. Touched: False
  Producing 4
  Performing intensive computation
  Received 4
  Finished intensive computation. Touched: True
  </code></pre>
  
  <p>This seems to indicate that <code>Consume</code> is given control while the <code>for</code> loop is running, as the <code>OutputAvailableAsync</code> task completes:</p>
  
  <pre><code>for (int j = 0; j &lt; 100000000; j++)
      ;
  </code></pre>
  
  <p>This would be unsurprising in a threaded model. But if no additional threads are involved, how can <code>Produce</code> yield control in the middle of the <code>for</code> loop?</p>