.Net 4.5 introduced the new asynchronous programming model using the asyn and await keywords. Till now asynchronous programming is little complex and the debugging of the same is painful. Now with the help of the new asynchronous programming, developers can write simple codes to do the asynchronous tasks.
Asynchronous Programming
Asynchronous programming uses a single thread which will
schedule a process in an asynchronous way. Program execution will continue and
the UI will be responsive to the user. Typical scenario for an asynchronous
programming is a long running process like data backup, bulk data processing,
time consuming calculations, etc. We can schedule the time consuming work as an
asynchronous task and the user can continue with his work.
Consider the following Code, where we have a set of URLs.
Getting the web response and processing the same will take time. Depends on the
number of URLs in the list, time taken to complete the execution will increase.
private void LongRunningMethod()
{
List<string> urlList = GetSetupURLList();
foreach(var url in urlList)
{
byte[] urlContents = GetContents(url);
ProcessTheContent(urlContents);
}
}
private byte[] GetContents(string url)
{
var data = new MemoryStream();
var webRequest = (HttpWebRequest)WebRequest.Create(url);
using (WebResponse webResponse = webRequest.GetResponse())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
responseStream.CopyTo(data);
}
}
return data.ToArray();
}
Let us see, how we can convert the same to asynchronous
using the async and await keywords.
Step 1: Modify with built-in asynchronous API calls
Along with the async and await keywords, .Net 4.5 introduced
a set of asynchronous APIs like StorageFile.CopyAsync(),
HttpClient.DeleteAsync(), etc. Now, our method looks like
private byte[] GetContents(string url)
{
var data = new MemoryStream();
var webRequest = (HttpWebRequest)WebRequest.Create(url);
using (WebResponse webResponse = webRequest.GetResponseAsync())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
responseStream.CopyToAsync(data);
}
}
return data.ToArray();
}
Step 2: Use await to wait for a response
await indicate that we need the result or the processed
data from the asynchronous method for further processing.
For processing the response, we need to get the web
response first, so apply the “await” operator to indicate the system to wait
for the result.
using (WebResponse webResponse = await webRequest.GetResponseAsync())
{-----------------------------------}
Step 3:Use async to an asynchronous method
Once you add the await operator, you will get an error
for the method declaration. This indicate that the method is not asynchronous
and you are trying to perform an asynchronous operation from a normal method.
An asynchronous method should be denoted using the async keyword.
private async byte[] GetContents(string url)
{------------------------------------}
Step 4: Specify return type as Task/Task<type>
Now, you will get another error near the return type. An
asynchronous method should return either a Task or a Task<Type> data
only.
private async Task<byte[]> GetContents(string url)
{------------------------------------}
Step 5: Naming convention - Asynchronous method name
should end with Async
Rename the method from GetContents to GetContentsAsync
private async Task<byte[]> GetContentsAsync(string url)
{------------------------------------}
Now, let us modify the calling method- LongRunningMethod
to use our new asynchronous method.
i.
Change
method name
byte[] urlContents =GetContentsAsync(url);
ii.
Add await
byte[] urlContents = await GetContentsAsync(url);
iii.
Add async
private async void LongRunningMethod()
{…………………………………………..}
iv.
Modify the return type
private async Task LongRunningMethod()
{…………………………………..}
v.
Modify the method name
private async Task LongRunningMethodAsync()
{………………………………………….}
Now, both the methods are converted into asynchronous
methods.
private async Task LongRunningMethodAsync()
{
List<string> urlList = GetSetupURLList();
foreach (var url in urlList)
{
byte[] urlContents = await GetContentsAsync(url);
ProcessTheContentAsync(urlContents);
}
}
private async Task<byte[]> GetContentsAsync(string url)
{
var data = new MemoryStream();
var webRequest = (HttpWebRequest)WebRequest.Create(url);
using (WebResponse webResponse = await webRequest.GetResponseAsync())
{
using (Stream responseStream = webResponse.GetResponseStream())
{
responseStream.CopyToAsync(data);
}
}
return data.ToArray();
}
When you run the asynchronous methods, you can notice
that the application is responsive even though the process is not over.
Conclusion
With the help of the .Net 4.5 asynchronous programming,
we can convert a synchronous method into an asynchronous method very easily.
Also the code is not so complex.