C# Corner

Asynchronous Programming with the Async CTP

The Async CTP and async and await keywords allow C# (and VB) developers to easily create more responsive applications. Here's how to get started with the Async CTP.

The Async Community Technology Preview (CTP) is a freely available download for Visual Studio 2010. The Async CTP includes the async and await keywords that are being considered for the next iterations of C# and VB.NET. Both language features allow you to more easily leverage the asynchronous programming features of the .NET Framework. The async keyword allows you to designate a method as being an asynchronous method. The await keyword allows you to indicate an expression to evaluate upon completion of an asynchronously invoked method.

Let’s go through the process of getting the Async CTP set up, followed by a look at some practical applications.

Getting Started
First download the Async CTP. Before installing the CTP ensure that you do not have the ASP.NET MVC 3 Beta or RC installed, as this will cause issues with the Async CTP. Trust me on this one. Also be sure that you do not have any Visual Studio 2010 hotfixes installed that have modified the C# or VB.NET runtimes -- as discussed here. Furthermore do not install the Visual Studio 2010 Service Pack 1 if you want to try out the Async CTP, as they are not currently compatible.

Now that you know what not to do, go ahead and install the Async CTP and verify that the examples are working correctly. If the examples do not compile correctly, double check that you do not have any of the aforementioned incompatible Visual Studio 2010 updates/hot fixes installed. I recommend installing the CTP on a development virtual machine. We will get started with creating an asynchronous method.

First, we'll set up our first project for the Aysnc CTP. Create a new .NET 4 C# Console Application and add a reference to AsynchCtpLibrary.dll. The AsynchCtpLibrary.dll file will be located in your Windows user Documents directory under “Microsoft Visual Studio Async CTP\Samples”.

Creating an asynchronous method
Creating an asynchronous method involves creating a method with the async keyword and returning either void, Task, or Task<T>. Let’s start out simple and create an asynchronous method with a void return type that simply greets the user given their name.

static async void GreetUserAsync(string name)
{
    await TaskEx.Run(() => Console.WriteLine("Hello, {0}", name)); 
}

GreetUserAsync is declared as an async method and awaits one task, which outputs “Hello, name” to the console where name is the given name to the function. TaskEx.Run creates a Task that executes the Console.WriteLine function. You may be asking why couldn’t I simply call Console.WriteLine("Hello, {0}", name)) within GreetUserAsync? The answer is you can, but then the GreetUserAsync method would execute synchronously. The await expression will call the created task, allow the main thread to run, and will force the GreetUserAsync function to return once its task has completed.

Calling the asynchronous method:

static void Main(string[] args)
{
   Console.WriteLine("Async CTP Simple Console App");
   Console.Write("Name:");
   string name = Console.ReadLine();
   Console.WriteLine("Calling asynch method...");
   GreetUserAsync(name);
   Console.ReadLine();
}

A more complex example
Now that we have covered the basics, let’s create a more complex application that takes a given number and performs several calculations on the method in parallel and displays the results in real-time. The application will compute the absolute value, square root and cube of a given number and compute a total once the other calculations have finished.

The first step is to open up Visual Studio 2010 and create a new WPF C# Application. Next add a reference to AsynchCtpLibrary.dll just as we did in the previous example. Now open up the MainWindow.xaml.cs and insert the following markup between into the element component.

  	 <StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label>Number</Label>
                <TextBox Name="txtNumber" MinWidth="100"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label>Absolute Value</Label>
                <Label Name="lblAbsVal"></Label>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label>Square root</Label>
                <Label Name="lblSqrtVal"></Label>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label>Cube</Label>
                <Label Name="lblCubeVal"></Label>
            </StackPanel>
            <StackPanel Orientation="Horizontal">
                <Label>Total</Label>
                <Label Name="lblTotalVal"></Label>
            </StackPanel>
            <Button Name="btnCompute" Click="btnCompute_Click">Compute</Button>
        </StackPanel>

[Click on image for larger view.]
Figure 1.

Run the application and you ensure that your application looks like the above screen shot. Now that our GUI is created we can start adding the core logic to our application. We’ll start out with adding the asynchronous method to calculate the absolute value of a given number.

async Task<double> ComputeAbsAsync(double number)
{
    await TaskEx.Delay(1000);
    return await TaskEx.Run<double>(new Func<double>(() => System.Math.Abs(number)));
}

The ComputeAbsAsync method contains two await expressions. The first await expression tells the method to wait for one second asynchronously. The second await expression creates and runs a task that computes the absolute value of the given number. Next we will add the ComputeSqrtAsync method which will compute the square root of a given number asynchronously.

async Task<double> ComputeSqrtAsync(double number)
{
    await TaskEx.Delay(1000);
    return await TaskEx.Run<double>(new Func<double>(() => System.Math.Sqrt(number)));
}

As you can see the method is almost identical to the ComputeAbsAsync method. Feel free to remove the TaskEx.Delay in your application. I added the delay to more easily display that the main thread is still active during the asynchronous method calls. You may be wondering if there is any easy way to refactor the code to allow you to execute a given Task asynchronously. The answer is a resounding yes. It turns out that the await expression can execute any Task or Task<T> in an asynchronous manner. We’ll execute the cube function in this manner within our ComputerResultsAsync method.

async Task<double> ComputeResultsAsync(double number)
{
     Task<double> cubeTask = TaskEx.Run<double>((() => System.Math.Pow(number, 3)));
     double absVal = await ComputeAbsAsync(number);
     lblAbsVal.Content = absVal;
     double sqrtVal = await ComputeSqrtAsync(number);
     lblSqrtVal.Content = sqrtVal;
     double cubeVal = await cubeTask;
     lblCubeVal.Content = cubeVal;
     return absVal + sqrtVal + cubeVal;
}

The ComputeResultsAsync method first creates a Task<double> that will calculate the cube of the given number. Next we await the ComputeAbsAsync, ComputeSqrtAsync methods as well as the cubeTask. Between each await we update the displayed value on the form to the result of pertinent calculation. Lastly, we return the total of all of the calculations. You may have noticed that each of our async methods returns a Task<double> in their respective definitions, but actually returns a double when invoked through an await expression. If your async method does not need to return a result you can simply return void or Task, as we did in the first example.

Now that our core application logic has been implemented it is time to wire up the Compute button click event and update our form.

private async void btnCompute_Click(object sender, RoutedEventArgs e)
{
    double number = double.Parse(txtNumber.Text);
    double total = await ComputeResultsAsync(number);
    lblTotalVal.Content = total;
}

In our button click event, we retrieve the number the user entered into the textbox, call the ComputeResultsAsync method asynchronously and update the displayed total. The button click event itself has been declared as an asynchronous event. By making the click event execute asynchronously we are able to easily invoke the ComputeResultsAsync method asynchronously and update the displayed result once the total has been calculated.

Finishing Touches
The application is completed as is, but can use some further refinement. The application is completed and will function correctly if the Compute button is clicked in succession, but it will end up creating many Task objects. Also the results are not cleared before a new computation is executed. To fix the first issue we can simply disable the compute button at the beginning of the click event and re-enable it once the total has been displayed. To fix the second issue we will clear any labels that display the calculated results before the new results are calculated. The updated button click event code is:

private void ClearResults()
{
    lblAbsVal.Content = string.Empty;
    lblCubeVal.Content = string.Empty;
    lblSqrtVal.Content = string.Empty;
    lblTotalVal.Content = string.Empty;
}

private async void btnCompute_Click(object sender, RoutedEventArgs e)
{
    btnCompute.IsEnabled = false;
    ClearResults();
    double number = double.Parse(txtNumber.Text);
    double total = await ComputeResultsAsync(number);
    lblTotalVal.Content = total;
    btnCompute.IsEnabled = true;
}

Our application is now completed and fully functional!


[Click on image for larger view.]
Figure 2.

Conclusion
The new language features async and await integrate very smoothly with the existing Task Parallel Library in .NET 4 and definitely make it easier to both create and call asynchronous methods. I highly recommend checking out the Asynch CTP if you are interested in asynchronous programming and/or new C# language features coming down the pipe.

About the Author

Eric Vogel is a Senior Software Developer for Red Cedar Solutions Group in Okemos, Michigan. He is the president of the Greater Lansing User Group for .NET. Eric enjoys learning about software architecture and craftsmanship, and is always looking for ways to create more robust and testable applications. Contact him at [email protected].

comments powered by Disqus

Featured

  • Hands On: New VS Code Insiders Build Creates Web Page from Image in Seconds

    New Vision support with GitHub Copilot in the latest Visual Studio Code Insiders build takes a user-supplied mockup image and creates a web page from it in seconds, handling all the HTML and CSS.

  • Naive Bayes Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the naive Bayes regression technique, where the goal is to predict a single numeric value. Compared to other machine learning regression techniques, naive Bayes regression is usually less accurate, but is simple, easy to implement and customize, works on both large and small datasets, is highly interpretable, and doesn't require tuning any hyperparameters.

  • VS Code Copilot Previews New GPT-4o AI Code Completion Model

    The 4o upgrade includes additional training on more than 275,000 high-quality public repositories in over 30 popular programming languages, said Microsoft-owned GitHub, which created the original "AI pair programmer" years ago.

  • Microsoft's Rust Embrace Continues with Azure SDK Beta

    "Rust's strong type system and ownership model help prevent common programming errors such as null pointer dereferencing and buffer overflows, leading to more secure and stable code."

  • Xcode IDE from Microsoft Archrival Apple Gets Copilot AI

    Just after expanding the reach of its Copilot AI coding assistant to the open-source Eclipse IDE, Microsoft showcased how it's going even further, providing details about a preview version for the Xcode IDE from archrival Apple.

Subscribe on YouTube

Upcoming Training Events