Understanding Asynchronous Methods

Asynchronous methods have been part of ASP.NET for a while, but as something of an afterthought. Web API adopts asynchronous methods throughout its API. They are optional in controllers, but many of the classes that customize the way that Web API processes requests define only asynchronous methods.

Asynchronous methods are one of the most misunderstood aspects of web application development. In the sections below we’ll go over the benefit that they offer, dispel a commonly held misconception, and demonstrate the patterns we’ll need to deal with asynchronous methods in Web API.

Understanding the problem Asynchronous methods solve

When writing action methods-or any part of a web application-the natural tendency is to think about the part that a single request follows through the code. Let’s assume we have a controller that computes the page size of a web page. The action method, PageSize, in the controller makes a request to remote web server, and after the remote website responds we get the data we need and can return the result.

The handler that is processing the request has nothing to do except wait during the n milliseconds it takes for the action method to send the HTTP request to remote website and receive the response.

This isn’t problem when we are thinking about only one request, but it causes problems for the overall application. Imagine the page size controller is being run in a web application server that processes only one request at a time and that all the requests target the GetPageSize action method. In such a situation, the server can process two incoming client requests a second, assuming it takes 500 milliseconds for a roundtrip to a remote server.

 

 

 

 

 


The handler can start processing the request only when it has finished processing the previous one, and for the majority of the time the handler is sitting idle. The problem isn’t the work that the action method is performing-it is the way that the handler and the action method work together. The solution is to perform the request to remote server asynchronously, which frees up the handler to process other incoming client requests instead of waiting for the remote server’s response.

Method Signature

Public async Task<long> GetPageSize()

{

Byte[] remoteData  = await wc.DownloadDataTaskAsync(TargetUrl);

….

}

The async keyword is applied to the method definition, and the result is changed to Task<long>, which means a Task object that will yield a long value when it completes. This arrangement doesn’t change the work that the action method performs, but it does mean that the handler is free to handle other client requests while the action method is waiting for the response from remote server.