Async & Await in C# 5.0

Most software engineers are used to programming in a linear manner, at least that is how they are taught when they begin their careers.

Linear versus nonlinear code

The following figure assumes that we have an order system in place that will help us to fetch a collection of orders from somewhere.

The flow of an event-based system is such that it fires off a call somewhere and expects the result to be delivered through a raised event, can be visualized like the diagram in the following figure.

Introducing a new pattern

To simulate a small portion of a real order system, the OrderHandler and Order will look like the following:


class Order
{
    public string OrderNumber { get; set; }
    public decimal OrderTotal { get; set; }
    public string Reference { get; set; }
}

class OrderHandler
{
    private readonly IEnumerable _orders;
    public OrderHandler()
    {
        _orders = new[]
        {
            new Order {OrderNumber = “F1”,OrderTotal = 100,Reference = “Filip”},
            new Order {OrderNumber = “F1”,OrderTotal = 100,Reference = “Filip” }
        };
    }

    public IEnumerable GetAllOrders()
    {
        return _orders;
    }
}

As this is about asynchronous programming, we want to have something to ask for in an asynchronous manner. In order to simulate this, we can simply modify GetAllOrders() as follows:

public IEnumerable GetAllOrders()
{
    System.Threading.ManualResetEvent(false).WaitOne(2000);
    return _orders;
}

Now we will  create a new blank Windows 8 Store Application project, then add the following XAML to the MainPage.xaml:


   <Grid.RowDefinitions>

         <ProgressBar.RenderTransform>

   <button></button>

Before we can actually run the application, we need to add some things to the code file as well.

public MainPage()
{
    this.InitializeComponent();
    Information.Text = “No orders have been loaded yet.”;
}

private void LoadOrders_Click(object sender, RoutedEventArgs e)
{
    OrderLoadingProgress.Visibility = Visibility.Visible;
    var orderHandler = new OrderHandler();
    var orders = orderHandler.GetAllOrders();
    OrderLoadingProgress.Visibility = Visibility.Collapsed;
}

Now you can run the application you should see something like the following:

Now when you press the Load orders button, you will notice that you will not see any loading indicator and that the button is left in its pressed state for 2 seconds. This is because we are locking up the application.

In previous C# versions, we could have solved this by wrapping the code in a BackgroundWorker. That when finished would have raised an event in which we had to invoke a delegate in order for us to change the UI. This is a non-linear approach which tends to mess up the readability of the code. In an older application that is not WinRT, using a BackgroundWorker would have looked something like this:

public sealed partial class MainPage : Page
{
    private BackgroundWorker _worker = new BackgroundWorker();
    public MainPage()
    {
        InitializeComponent();
        _worker.RunWorkerCompleted += WorkerRunWorkerCompleted;
        _worker.DoWork += WorkerDoWork;
    }

    void WorkerDoWork(object sender, DoWorkEventArgs e)
    {
        var orderHandler = new OrderHandler();
        var orders = orderHandler.GetAllOrders();
    }

    private void LoadOrders_Click(object sender, RoutedEventArgs e)
    {
        OrderLoadingProgress.Visibility = Visibility.Visible;
        _worker.RunWorkerAsync();
    }

    void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Dispatcher.BeginInvoke(new Action(() =>
            {
                // Update the UI
                OrderLoadingProgress.Visibility = Visibility.Collapsed;
            }));
    }
}

The BackgroundWorker is what is known as event-based asynchronicity, the pattern is called event-based asynchronous pattern (EAP).

In WinRT however, there is no BackgroundWorker so we have to adapt to the new linear approach, which is only a good thing!
Our solution to this is to adapt to the new pattern introduced in .NET 4.5, async & await. When we use async & await, it is mandatory that we are using it together with the task parallel library (TPL).


private async void LoadOrders_Click(object sender, RoutedEventArgs e)
{
    OrderLoadingProgress.Visibility = Visibility.Visible;
    var orderHandler = new OrderHandler();
    var orderTask = Task<IEnumerable>.Factory.StartNew(() =>
        {
            return orderHandler.GetAllOrders();
        });
    var orders = await orderTask;
    Orders.Items.Clear();
    foreach (var order in orders)
        Orders.Items.Add(order);
    OrderLoadingProgress.Visibility = Visibility.Collapsed;
}

We can now run this application and load the orders without the UI locking up and then having a nice list of order numbers presented to us.

Thank you 🙂

Keep It Simple & Straightforward!

~:H}{H:~

Advertisements

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