Sunday, November 18, 2012

C# Async Await Example in WPF

C# 5.0 and .NET Framework 4.5 bring to developer a very nice feature called Asynchronous Programming. Asynchronous Programming is based on Task Parallel Library (TPL). As you probably know traditional techniques for writing asynchronous programs are very complicated in many aspects, so Async Programming comes to make our life easier when we write Multithreading applications. 

Today we'll see a very simple example of Async Programming using Async, Await and Task keywords in WPF application. Let's build a simple WPF application with a button and a textbox. By pressing the button we call for some slow method (I named it SlowDude :). I don't want GUI will be locked until the method will finish his job. In other words I want to call that method asynchronously.

C# 5.0 Asynchronous Programming with WPF GUI

Ok here is our simple XAML:
<Window x:Class="WpfAsync.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CodeArsenal.net" Height="180" Width="360">

    <DockPanel>
        <Button Name="buttonAsync" Height="50" Content="Async Example" 
                DockPanel.Dock="Top" Click="buttonAsync_Click"/>
        
        <TextBox Name="textBoxResults" DockPanel.Dock="Bottom" Margin="0,20,0,0"
                 TextWrapping="Wrap"
                 FontFamily="Lucida Console" 
                 FontSize="10"
                 AcceptsReturn="True"/>
    </DockPanel>
</Window>
So, as you can see, by clicking on the button we will fire buttonAsync_Click method.
Let's see now the code behind:
private async void buttonAsync_Click(object sender, RoutedEventArgs e)
{
    buttonAsync.IsEnabled = false;
    
    var slowTask = Task<string>.Factory.StartNew(() => SlowDude());
    
    textBoxResults.Text += "Doing other things while waiting for that slow dude...\r\n";
    
    await slowTask;
    
    textBoxResults.Text += slowTask.Result.ToString();
    
    buttonAsync.IsEnabled = true;
}

private string SlowDude()
{
    Thread.Sleep(2000);
    return "Ta-dam! Here I am!\r\n";
}
Did you notice the async modifier in buttonAsync_Click method signature? This is crucial, because async modifier tells to compiler that this method contains code that will run asynchronously using await keyword. 

Following code line actually calls for SlowDude method in asynchronous manner:
var slowTask = Task<string>.Factory.StartNew(() => SlowDude());    
Ok now let's look on following line:
await slowTask;
This command means - do other stuff that are between these two lines of code, without locking the main thread, and once SlowDude is finished proceed further.

Well, I think, Async Programming is a great thing, and will make our life a lot easier when it comes to Multithreading problems. Well done, Microsoft!
Download the source code (Visual Studio 2012 project).

If you still working with Visual Studio 2010 Framework 4.0 then take a look at this post - WPF Start New Background Process using Task

7 comments:

  1. Very well. Thanks!

    ReplyDelete
  2. Nicely written article. Thanks for putting this together. My only concern is that there are now multiple ways to deal with multi-thread async operations. That makes it confusing. In the end, this was added to .NET to simplify what already existed (multi-threaded async ops) . That is the whole point. No new functionality just syntactical sugar. A different way of doing the same thing. See http://www.c-sharpcorner.com/UploadFile/rmcochran/asyncmultithread05122007134057PM/asyncmultithread.aspx for example of old way...

    ReplyDelete
  3. @barrypicker - Just to make sure future readers are not confused, the async-await method is *not* multi-threaded. If you truly want multi-threaded, then you have to do additional programming.

    ReplyDelete
  4. Great post!
    I spent several hours reading through MSDN articles on starting some asynchronous threads and your explanation was the first one that came down to relevant points immediately.
    Thanks a lot!

    ReplyDelete