C# Control Flow With Await Async And Threading
<p>Microsoft says: “The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available.”</p>

<p>Here is the web request example Microsoft uses for explaining the use of async and await. (<a href="https://msdn.microsoft.com/en-us/library/mt674880.aspx" rel="nofollow">https://msdn.microsoft.com/en-us/library/mt674880.aspx</a>). I pasted the relevant part of the sample code at the end of the question. </p>

<p>My question is, after each “var byteArray = await client.GetByteArrayAsync(url);”statement, control returns to CreateMultipleTasksAsync method, then invoking another ProcessURLAsync method. And after three downloads are invoked, then it starts to wait on the completion of the first ProcessURLAsync method to finish. But how can it proceed to the DisplayResults method if ProcessURLAsync is not running in a seperate thread? Because if it is not on a different thread, after returning control to CreateMultipleTasksAsync, it can never complete. Can you provide a simple control flow so that I can understand?</p>

<p>Let's assume the first client.GetByteArrayAsync method finished before Task download3 = ProcessURLAsync(..), when exactly is the first DisplayResults called?</p>

<pre><code>private async void startButton_Click(object sender, RoutedEventArgs e)
    {
        resultsTextBox.Clear();
        await CreateMultipleTasksAsync();
        resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";
    }


    private async Task CreateMultipleTasksAsync()
    {
        // Declare an HttpClient object, and increase the buffer size. The
        // default buffer size is 65,536.
        HttpClient client =
            new HttpClient() { MaxResponseContentBufferSize = 1000000 };

        // Create and start the tasks. As each task finishes, DisplayResults 
        // displays its length.
        Task&lt;int&gt; download1 = 
            ProcessURLAsync("http://msdn.microsoft.com", client);
        Task&lt;int&gt; download2 = 
            ProcessURLAsync("http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);
        Task&lt;int&gt; download3 = 
            ProcessURLAsync("http://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);

        // Await each task.
        int length1 = await download1;
        int length2 = await download2;
        int length3 = await download3;

        int total = length1 + length2 + length3;

        // Display the total count for the downloaded websites.
        resultsTextBox.Text +=
            string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
    }


    async Task&lt;int&gt; ProcessURLAsync(string url, HttpClient client)
    {
        var byteArray = await client.GetByteArrayAsync(url);
        DisplayResults(url, byteArray);
        return byteArray.Length;
    }


    private void DisplayResults(string url, byte[] content)
    {
        // Display the length of each website. The string format 
        // is designed to be used with a monospaced font, such as
        // Lucida Console or Global Monospace.
        var bytes = content.Length;
        // Strip off the "http://".
        var displayURL = url.Replace("http://", "");
        resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
    }
}
</code></pre>