C#

Running a synchronous method in an asynchronous context

In WinRT a significant portion of all native methods are asynchronous. Using an asynchronous method is very easy an can help you to speed up you application. The requirement to use an async method is that the calling method has an async modifier.

It’s easy to use async methods from a native API, but it can be useful as well to run synchronous operations off the UI thread. This should be done to prevent the UI thread from beeing blocked by time-consuming or resource-intensive operations like calculating ϖ or the answer to the ultimate question for the life, the universe and everything.

To show you how to run things like this asynchronously we take the following synchronous method:

private void synchonousMethod()
{
    do
    {
        i++;
    }
    while (i < Int32.MaxValue / 2);
}

This method obviously lacks the async and await keywords and it’s usual implementation would be something like this:

int i;
private void Button_Click_1(object sender, RoutedEventArgs e)
{
    i = 0;//reset i
    textBlock.Text += "starting...r";
    synchonousMethod();
    textBlock.Text += i.ToString() + "r";
}

(To test it just create a new C# Metro application, insert a Button and a TextBlock (called ‘textBlock’) into the XAML and attach the Click event…)

The Button_Click_1 event handler will run synchronously, freezing the UI thread for a few seconds.

An async implementation would look like this:

private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    i = 0;//reset i
    Task timeConsumingOperation = Task.Run(new Action(synchonousMethod));
    textBlock.Text += "started taskr";
    await timeConsumingOperation;
    textBlock.Text += i.ToString() + "r";
}

Notice the async and await keywords! When this event handler is executed the UI thread won’t be blocked. The ‘started task’ text will appear instantaneously as well. As the timeConsumingOperation (Task) is awaited, the UI thread will continue to run (you can still interact with the button, unlike the first case) and as soon as the synchronousMethod returns, the timeConsumingOperation will return too and the next line is executed.

You should be able to change the synchronousMethod (private void) into something like private int and use int foo = await timeConsumingOperation; to get back the result of a synchronous calculation or similar.

Have faith in async – you won’t be disappointed =p

One comment

Leave a Reply to Martin Bojnanský Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.