When you are developing interactive software, such as Windows Forms or Windows Presentation Foundation applications, you will write code that reacts to user input. If the operation requested by the user is slow to execute and synchronous, it will block the user interface (UI) thread. This prevents controls from updating and causes user input to be ignored or delayed. If the blocking process is very long or the user makes repeated attempts to interact with the UI, the operating system may flag the application as unresponsive. In some cases the user will be asked if they want to terminate the program. This gives a poor user experience.
To avoid these problems you should ensure that any process that is slow to complete is executed asynchronously. Here, the operation is launched in a new thread, allowing the UI thread to continue to respond normally and the application to remain responsive.
There are several ways in which asynchronous code can be created. For example, threads can be launched manually or you can use the BeginInvoke and EndInvoke methods provided by delegates. On completion of an asynchronous task, when you may need to work with its results, you can raise events or use callbacks to continue the processing. However, these approaches lead to complex code structures that can be difficult to read and maintain.
To help overcome these problems, the compilers provided with the .NET framework version 4.5 recognise new keywords that allow asynchronous code to appear almost as simple as its synchronous equivalent. Code that would be difficult to write and maintain in earlier versions can now be replaced with much simpler variants.
In this article we'll look at the differences between one of the older ways of creating asynchronous code and the new approach in .NET 4.5, using examples written in C#. We'll compare the two asynchronous approaches with a synchronous version of the same code. All of the examples are combined in a single Windows Forms project, which you can download using the link at the beginning of this article.
Creating the Test Form
To begin, create a new Windows Forms application, ensuring that you target version 4.5 of the .NET framework. Add four buttons, three progress bars and four labels to the automatically generated form, arranging them as shown below. We'll be setting up the first three buttons to animate the corresponding progress bars for a period before setting a value in the label to the right. Each of these buttons will perform the same task using a different synchronous or asynchronous approach. We'll use the fourth button to test the responsiveness of the window at run-time.
Configure the new controls using the properties in the following table:
|Control Name||Type||Special Properties|
|SynchronousButton||Button||Text = "Synchronous"|
|SynchronousLabel||Label||Text = "No Time"|
|CallbackButton||Button||Text = "Asynchronous Callback"|
|CallbackLabel||Label||Text = "No Time"|
|AsyncButton||Button||Text = "Async / Await"|
|AsyncLabel||Label||Text = "No Time"|
|CheckButton||Button||Text = "Check Responsiveness"|
|CheckLabel||Label||Text = "No Time"|
Responsiveness Test Button
The button at the bottom of the form will allow us to check the responsiveness of the program. When clicked, we'll immediately set the label to its right to show the current time, with millisecond accuracy. If the program is responding correctly, the time will be set straight away. If the window is unresponsive, the time will update.
Add a Click event handler to the button with the following code:
private void CheckButton_Click(object sender, EventArgs e)
CheckLabel.Text = DateTime.Now.ToString("HH:mm:ss.fff");
Try running the program and clicking the button to ensure that it works correctly.
21 October 2012