.NET Zone is brought to you in partnership with:

Jeremy Likness was named Silverlight MVP of the Year in 2010. Now Senior Consultant and Technical Project Manager for Wintellect, LLC, he has spent the past decade building highly scalable web-based commercial solutions using the Microsoft technology stack. He has fifteen years of experience developing enterprise applications in vertical markets including insurance, health/wellness, supply chain management, and mobility. He is the creator of the popular MVVM framework Jounce and an open source Silverlight Isolated Storage Database System called Sterling. Likness speaks and blogs frequently on Silverlight, MEF, Prism, Team Foundation Server, and related Microsoft technologies. Jeremy is a DZone MVB and is not an employee of DZone and has posted 46 posts at DZone. You can read more from them at their website. View Full User Profile

Synchronous to Asynchronous Explained

08.12.2012
| 2350 views |
  • submit to reddit

I've posted several articles about the new async and await keywords that are available in Visual Studio 2012, but I still see some people struggle with the concept. How do you make a task asynchronous? When and where do you use the async keyword?

The answer is not simple because the need to process asynchronously depends on a variety of factors. There is overhead when you create a thread. It allocates memory and creates a new synchronization context. Having a thread communicate with other threads is even more expensive and adds complexity to your code. Fortunately, the teams at Microsoft introduced the Task Parallel Library to help simplify how you work with threads. I strongly recommend learning as much as you can about the Task object if you wish to master asynchronous programming.

There are many cases where the use of asynchronous code is straightforward, and my intent with this article is to show a very simple example to help illustrate how to create an asynchronous task and then use the new keywords to interact with it. The example is a very trivial program that computes prime numbers between 2 and 999999. You can follow along and build this in about 5 minutes.

First, create a new WPF application from Visual Studio 2012 that targets the .NET Framework 4.5. Add a simple listbox to MainWindow.xaml so the entire XAML looks like this:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox x:Name="PrimeNumbers"/>
    </Grid>
</Window>

Now add a new class and call it PrimeChecker. This is a static class that will check to see if a number is a prime number. The algorithm we'll use is a brute force algorithm that divides numbers until it finds a match:

public static class PrimeChecker
{
    public static bool IsPrime(int x)
    {
        if (x < 2) return false;
        if (x == 2) return true;
        for(var y = 2; y < x; y++)
        {
            if (x % y == 0)
            {
                return false;
            }
        }
        return true;
    }
}

In the code-behind for the MainWindow, declare an observable collection to hold the prime numbers:

private ObservableCollection<int> _primeNumbers =
    new ObservableCollection<int>();

Hook into the Loaded event for the page:

public MainWindow()
{
    InitializeComponent();
    Loaded += MainWindow_Loaded;            
}

Once the page is loaded, you will assign the observable collection to the source for the list box control, then iterate through numbers and call the checker to only add those numbers that are prime:

void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    PrimeNumbers.ItemsSource = _primeNumbers;
    for(var x = 1; x < 999999; x++)
    {
        if (PrimeChecker.IsPrime(x))
        {
            _primeNumbers.Add(x);
        }
    }
}

You can now compile and run the program. If you set a breakpoint in the loop, you will see that prime numbers are being computed and added to the collection. However, the application itself will freeze and you won't see anything. This is because all of the computations are happening on the same thread, which happens to be the main UI thread. This will freeze that thread and prevent the system from updating the display and accepting user input. This is obviously not the desired effect. What would make more sense is to do the heavy lifting, or the brute force algorithm to determine if a number is prime, on a separate thread that does not block the UI. This is easily done in a few steps. First, add a new method to the PrimeChecker class. Note I'm following the standard convention of marking an asynchronous method with the Async suffix:

public static Task<bool> IsPrimeAsync(int x)
{
    return Task.Run(() => IsPrime(x));
}

That's it. That's the only code needed to take the computation and run it on a separate thread. The Task takes care of it. Notice that the return is typed to the actual value we want to inspect (boolean) but wrapped in a Task object. Now that you have the work being performed asynchronously, how do you interact with the result? This takes two simple steps.

First, declare your intent to wait for an asynchronous task by prefixing the method with the async keyword. We are still going to use the MainWindow_Loaded method, so it will now look like this:

async void MainWindow_Loaded(object sender, RoutedEventArgs e)

Next, change the call to check for a prime number to use the asynchronous method, and then simply wait for it. The await keyword specifies that the task should run and return a result, but the thread should not block while waiting. It is as simple as changing the line to this:

if (await PrimeChecker.IsPrimeAsync(x))

And that's the beautify of the new keywords. Without those keywords, you would need to explicitly wait for the thread, either by using a helper method on the Task or by using events and registering for a completion. This would fragment your code and if you had a lot of asynchronous tasks could render it very difficult to read and maintain. The new keywords make it easy to both create asynchronous methods and consume them inline without blocking. The entire method now looks like this:

async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    PrimeNumbers.ItemsSource = _primeNumbers;
    for(var x = 1; x < 999999; x++)
    {
        if (await PrimeChecker.IsPrimeAsync(x))
        {
            _primeNumbers.Add(x);
        }
    }
}
When you run the application this time, you'll see the list quickly start to fill with the list of prime numbers. You can scroll the list while it is computing because the main thread is no longer frozen by the brute force computations.
Published at DZone with permission of Jeremy Likness, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)