Asynchronous Programming
Asynchronous vs Synchronous Program Execution
With synchronous execution the program is executed line by line, one at a time.
Wnen a function is called, the program execution has to wait until the function returns.
With asynchronous execution, when a function is called, the program execution continues to the next line, without waiting for the function to complete.
You provide a callback for the function, so the program can be notified when the function completes.
Asynchronous execution improves the responsiveness of your application.
Traditional approaches in C# to use asynchronous execution involved using multi-threading and callbacks.
New approach since .NET 4.5 is called the Task based Asynchronous model using the Async and Await keywords.
The application for asynchronous programming is when using blocking operations and can be:
1. Accessing Files
2. Accessing Database
3. Calling Web Services or API's
If you call a method that download some html for example, in synchronous execution your UI will be unresponsive until download is completed.
The following example shows how to write a Asynchronous method, so your program stays responsive while the download is busy.
public async Task DownloadHtmlAsync(string url)
{
var webClient = new WebClient();
var html = await webClient.DownloadStringTaskAsync(url);
using (var streamWriter = new StreamWriter(...))
{
streamWriter.Write(html); // this could be replaced by .WriteAsync to futher improve responsiveness, so it will change to: await streamWriter.WriteAsync(html);
}
}
All asynchronous methods start with the keyword 'async' and returns a Task object.
A Task object is an object that encapsulate the state of an asynchronous operation.
It can be in a non-generic form 'Task' (if your method is void) or a generic form 'Task<string>' if you need to return something.
By convention always add the Async suffix (DownloadHrmlAsync).
You also have to change method calls inside your async method to asynchronous, so they do not block processing.
Most methods in .NET has corresponding ...TaskAsync methods, and these needs to be used inside your asynchronous method.
We add the await operator infront of the asynchronous method inside our asynchronous method.
The await indicator indicates that the method that is called will take some time to complete.
When the compiler sees 'await' if immediately gives control back to the caller, in this case 'DownloadHtmlAsync', so the program continues after the call 'DownloadHtmlAsync'.
When the method with the await keyword completes the compiler continues to execute the next statement, in this case 'using (var streamWriter...'
Futher down in the method there is another potentially blocking operation called: streamWriter.Write(html);
public async Task<string> GetHtmlAsync(string url)
{
var webClient = new WebClient();
return await webClient.DownloadStringTaskAsync(url);
}
The await keyword can only be used in a method with the async keyword, so the button click calling the above method should be:
You use an await if the rest of the method cannot be executed until the result is ready.
private async void Button_Click(object sender, RoutedEventArgs e)
{
var html = await GetHtmlAsync("www.solomeet.com");
MessageBox.Show(html);
}
// you can also change it to this, and display a message that download is busy
private async void Button_Click(object sender, RoutedEventArgs e)
{
var getHtmlTask = GetHtmlAsync("www.solomeet.com");
MessageBox.Show("Busy downloading...");
var html = await getHtmlTask;
MessageBox.Show(html);
}