title: Inside a loop,does each async call get chained to the returned task using task's continuewith?
body: <p>The best practice is to collect all the <code>async</code> calls in a collection inside the loop and do <code>Task.WhenAll()</code>. Yet, want to understand what happens when an <code>await</code> is encountered inside the loop, what would the returned <code>Task</code> contain? what about further <code>async</code> calls? Will it create new tasks and add them to the already returned <code>Task</code> sequentially?</p>
  
  <p>As per the code below
  </p>
  
  <pre><code>private void CallLoopAsync()
  {
     var loopReturnedTask = LoopAsync();
  }
  
  private async Task LoopAsync()
  {
      int count = 0;
      while(count &lt; 5)
      {
         await SomeNetworkCallAsync();
         count++;
      }
  }
  </code></pre>
  
  <p>The steps I assumed are</p>
  
  <ol>
  <li><code>LoopAsync</code> gets called</li>
  <li><code>count</code> is set to zero, code enters while loop, condition is checked</li>
  <li><code>SomeNetworkCallAsync</code> is called,and the returned task is awaited</li>
  <li>New task/awaitable is created </li>
  <li>New task is returned to <code>CallLoopAsync</code>()</li>
  </ol>
  
  <p>Now, provided there is enough time for the process to live, How / In what way, will the next code lines like <code>count++</code> and further <code>SomeNetworkCallAsync</code> be executed?</p>
  
  <p>Update - Based on <a href="https://stackoverflow.com/users/400547/jon-hanna">Jon Hanna</a> and <a href="https://stackoverflow.com/users/263693/stephen-cleary">Stephen Cleary</a>:</p>
  
  <blockquote>
    <p>So there is one Task and the implementation of that Task will involve
    5 calls to NetworkCallAsync, but the use of a state-machine means
    those tasks need not be explicitly chained for this to work. This, for
    example, allows it to decide whether to break the looping or not based
    on the result of a task, and so on.</p>
  </blockquote>
  
  <p>Though they are not chained, each call will wait for the previous call to complete as we have used <code>await</code> (in state m/c, <code>awaiter.GetResult();</code>). It behaves as if five consecutive calls have been made and they are executed one after the another (only <em>after</em> the previous call gets <em>completed</em>). If this is true, we have to be bit more careful in how we are composing the async calls.For ex:</p>
  
  <p>Instead of writing </p>
  
  <pre><code>private async Task SomeWorkAsync()
  {
     await SomeIndependentNetworkCall();// 2 sec to complete
  
     var result1 = await GetDataFromNetworkCallAsync(); // 2 sec to complete
     await PostDataToNetworkAsync(result1); // 2 sec to complete
  }
  </code></pre>
  
  <p>It should be written </p>
  
  <pre><code>private Task[] RefactoredSomeWorkAsync()
  {
      var task1 =  SomeIndependentNetworkCall();// 2 sec to complete
  
      var task2 = GetDataFromNetworkCallAsync()
      .ContinueWith(result1 =&gt; PostDataToNetworkAsync(result1)).Unwrap();// 4 sec to complete
  
      return new[] { task1, task2 };
  }
  </code></pre>
  
  <p>So that we can say <code>RefactoredSomeWorkAsync</code> is faster by 2 seconds, because of the possibility of <em>parallelism</em></p>
  
  <pre><code>private async Task CallRefactoredSomeWorkAsync()
  {
     await Task.WhenAll(RefactoredSomeWorkAsync());//Faster, 4 sec 
     await SomeWorkAsync(); // Slower, 6 sec
  }
  </code></pre>
  
  <p>Is this correct? - Yes. Along with "<em>async all the way</em>", "<em>Accumulate tasks all the way</em>" is good practice. Similar discussion is <a href="https://stackoverflow.com/a/21072505/1661861">here</a></p>