Click here to Skip to main content
15,886,639 members
Articles / Desktop Programming / WPF
Tip/Trick

WPF with Asynchrony: Part 1

Rate me:
Please Sign up or sign in to vote.
4.67/5 (3 votes)
11 Sep 2012CPOL2 min read 39K   612   12   5
This article is about the new features added in C# 5.0 called “Asynchrony” and how we can use them to write asynchronous code which looks like synchronous code.

Introduction

This article is about the new features added in C# 5.0 called “Asynchrony” and how we can use them to write asynchronous code which looks like synchronous code. As we know, WPF applications run on the STA (Single Threaded Apartment) model. The thread which controls the UI is commonly known as the UI Thread. If we want to perform some long running tasks then we need to use Thread or BackGroundWorker and use Dispatcher to update the UI. This article will cover how we can achieve this complexity using Asynchrony with ease. 

Background

For better understanding of this article I would recommend reading on the requirements of Dispatcher, multithreading, and UI updates from a different thread in WPF. It also requires the knowledge of the Task class from the Task Parallel Library. It requires Visual Studio 2012 and .NET Framework 4.5.

Using the code

First of all let’s take an example of an application form .NET 4.0 where we need to perform some long running task on a different thread and need to update the UI.

UI:
XML
<StackPanel>
    <Button Content="Service Call" Click="ServiceCall_Click" />
    <ListView ItemsSource="{Binding Tests}" />
</StackPanel>
Code:
C#
public delegate void UpdateUI(string message);

/// <summary>
/// This the button click event for ServiceCall button on UI which performs              
/// the long running task and updated the UI.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ServiceCall_Click(object sender, RoutedEventArgs e)
{
    Thread asycnWork = new Thread(new ThreadStart(ServiceCall));
    asycnWork.Start();
}

/// <summary>
/// A long running service call.
/// </summary>
private void ServiceCall()
{
    // Consider the below line as a service call which takes some time.
    Thread.Sleep(2000);

    // Update the UI.
    Dispatcher.BeginInvoke(
          new UpdateUI(this.AddToTestsCollection),
        new object[] {   System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()}
    );
}

/// <summary>
/// Add the message to the collection
/// </summary>
/// <param name="message"></param>
private void AddToTestsCollection(string message)
{
    Tests.Add(message);
}

As we can see, we need to create a new thread and have to marshal back to the UI every time we want to update the UI.

Let’s see the new approach with Asycn – Await

C#
/// <summary>
/// Service call button click event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ServiceCall_Click(object sender, RoutedEventArgs e)
{
    ServiceCallAsycn();
}

/// <summary>
/// Long running service calls
/// We will use for loop to see that all the calls are made on the same thread
/// </summary>
/// <param name="items"></param>
private async void ServiceCallAsycn()
{
    for (int i = 0; i < 5; i++)
    {
        // Service call
        var s = await GetTestAsync(i);

        // Update the UI
        Tests.Add(s);
    }
}

/// <summary>
/// Service call
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
async Task<string> GetTestAsync(int i)
{
    await Task.Delay(2000);
    return i.ToString() + " Call - " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
}

Let us understand the “async” and “await” keywords and their responsibilities.

Async: It just denotes that the method is asynchronous and it has one or more await inside the method. If we don’t use any await in the method, it will give us the warning that the method will work synchronously.

Await: The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.

The following sentence is the heart of Asynchrony:

An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

Let us understand this sentence from our example:

When the call encounters await GetTestAsync(i), it will return the control back to the UI. After 2 seconds it will add the result to the Items which will become available on the UI. Here you can see that we don’t need to use Dispatcher’s BeginInvoke or TaskSchedular.FromCurrentSynchronizationContext(). Moreover, if we run the code we will see that all the results show the same thread and hence it does not introduce any new thread itself.

Conclusion

To sum up, “Asynchrony” makes the code very much simple and looks like synchronous code. Moreover it does not introduce any new thread itself. I will try to cover exception handling and more complex scenarios in part 2. Keep learning!!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
SuggestionBut if I still on VS 2010 with Framework 4.0? Pin
Coddioz24-Nov-12 3:02
Coddioz24-Nov-12 3:02 
GeneralRe: But if I still on VS 2010 with Framework 4.0? Pin
nelsonfsr22-Mar-13 1:50
nelsonfsr22-Mar-13 1:50 
GeneralMy vote of 5 Pin
Carsten V2.011-Sep-12 18:41
Carsten V2.011-Sep-12 18:41 
GeneralRe: My vote of 5 Pin
Bhavik Barot11-Sep-12 19:26
Bhavik Barot11-Sep-12 19:26 
GeneralRe: My vote of 5 Pin
Carsten V2.012-Sep-12 9:45
Carsten V2.012-Sep-12 9:45 
Hello Bhavik,

sorry, I've no suggestions at the moment.
I'll take some time over the weekend for brainstorming... Wink | ;)

But know, I'll use this new method for internet- and mailing-functionality. I think, that this is a safe and proper way for doing calls and requests, which could need some time to reply.
Do you know, is there new progress on this area, too? This would be very interesting.

Thanks in advance for your reply!

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.