Async and await in C# 5.0: purpose, practical considerations, and links for further reading

At the CS50x Miami Hackathon: answering TF Ricardo’s question about concatenation!

When async was first unveiled, Microsoft’s Eric Lippert explained (video @ 3:32-6:36) why async is such an exciting feature: it is cooperative multi-tasking via code routines implemented using continuation passing style.

Don’t worry – that’s just the teaser. I’m going to break it down into smaller pieces: 1) what problem is it trying to solve; 2) how is it trying to solve this problem; and 3) what issues or resources might you also want to consider.

What problem is it trying to solve?

Latency. Performance bottlenecks. We want to solve a problem, but because of processor cycles we might be waiting for the solution to come back. Sometimes, the laws of physics – e.g. signal travel – cause the latency. Other times, the latency is caused by our problem’s need for so many calculations because it takes a while for a solution to come back.

Before async, people split work into chunks to make efficient use of processors. Put differently, they ran other code that didn’t depend on the result they were awaiting. But as you can imagine, this made code hard to understand, debug, and maintain.

How is it trying to solve this problem?

Async allows you to structure your code in a logical order resembling synchronous code. You annotate your code with the keyword await. That keyword signals that a high latency operation may occur there. Then the compiler takes care of splitting your code into chunks for you. And Windows Runtime takes care of scheduling them all appropriately. Thus, async leverages the asynchronous support in the .NET Framework and the Windows Runtime. And as a result, you get all the advantages of asynchronous programming with a fraction of the effort.

Here is an example of how the code may be used:
MSDN source

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http; 
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it. 
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately. 
            //Task<int> getLengthTask = AccessTheWebAsync(); 
            //// You can do independent work here. 
            //int contentLength = await getLengthTask; 

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
                String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }


        // Three things to note in the signature: 
        //  - The method has an async modifier.  
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer. 
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // You need to add a reference to System.Net.Http to declare client.
            HttpClient client = new HttpClient();

            // GetStringAsync returns a Task<string>. That means that when you await the 
            // task you'll get a string (urlContents).
            Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

            // You can do work here that doesn't rely on the string from GetStringAsync.
            DoIndependentWork();

            // The await operator suspends AccessTheWebAsync. 
            //  - AccessTheWebAsync can't continue until getStringTask is complete. 
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
            //  - Control resumes here when getStringTask is complete.  
            //  - The await operator then retrieves the string result from getStringTask. 
            string urlContents = await getStringTask;

            // The return statement specifies an integer result. 
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
            return urlContents.Length;
        }


        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

// Sample Output: 

// Working . . . . . . . 

// Length of the downloaded string: 41564.

 

What issues or resources might you also want to consider?

As you would expect, many in the developer community have discussed async online since it was introduced. And there are many resources you can locate to help you determine whether and when to use it. To that end, I’ve included links above and include a few more below:

I am loving learning about C#, hope that you took something from this, and would be grateful if you would follow my blog and share in this journey with me up The Coding Ladder!

Advertisements

One thought on “Async and await in C# 5.0: purpose, practical considerations, and links for further reading

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s