The goal
of this post is to explain the usage of async and await keywords, how could be
used to convert the existing synchronous method to asynchronous method.
Pre-Requisites:
Working
knowledge of Task
Details
of what async and await mean can be found in MSDN.
Asynchrony is essential for activities that are potentially
blocking, such as when your application accesses the web(or writing big stream
to file). Access to a web resource sometimes is slow or delayed. If such an
activity is blocked within a synchronous process, the entire application must
wait. In an asynchronous process, the application can continue with other work
that doesn't depend on the web resource until the potentially blocking task
finishes. In this scenario, the usage of wait and async keywords helps to
achieve Asynchrony.
Eg:
Download the RSS feed from the web asynchronously.
Implementation of this example helps to differentiate the ease
of code to achieve Asynchrony with/without async and await keywords.
This
could be achieved in 3 ways
Synchronous
- UI will
be unresponsive until there is no response from the feed server. In the Dot net
4.5 era, nobody will follow this way.
Code snippet to achieve this:
internal static string
GetFeed()
{
HttpWebRequest request = HttpWebRequest.Create(@"http://rss.news.yahoo.com/rss/entertainment") as HttpWebRequest;
WebResponse response =
request.GetResponse();
Stream responseStream =
response.GetResponseStream();
return new StreamReader(responseStream).ReadToEnd();
}
AsyncCallback
- UI will be responsive, but code becomes bulky with extra
overhead of callbacks. Before introducing the async and await keywords, this
way was very useful to achieve Asynchrony.
Code snippet to achieve this:
internal static void GetFeedUsingAsyncCallback()
{
HttpWebRequest request = HttpWebRequest.Create(@"http://rss.news.yahoo.com/rss/entertainment")
as HttpWebRequest;
request.BeginGetResponse(new AsyncCallback(OnGetResponse), request);
}
private static void OnGetResponse(IAsyncResult ar)
{
HttpWebRequest
myHttpWebRequest = ar.AsyncState as HttpWebRequest;
WebResponse
response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(ar);
//
Read the response into a Stream object.
Stream
responseStream = response.GetResponseStream();
string
content = new StreamReader(responseStream).ReadToEnd();
//Raise
event here
}
Async
and Await
·
Responsive UI
·
Clean code
·
Debugging becomes easier as sequential
control flow.
Code snippet to achieve this:
async internal static Task<string>
GetFeedAsync()
{
HttpWebRequest request = HttpWebRequest.Create(@"http://rss.news.yahoo.com/rss/entertainment")
as HttpWebRequest;
WebResponse response = await request.GetResponseAsync();
Stream
responseStream = response.GetResponseStream();
return
await new StreamReader(responseStream).ReadToEndAsync();
}
Assume if Async method is not available, how we will convert it to async
method?
async internal static Task<string> GetStringAsyncExtesion(this HttpWebRequest
request)
{
TaskCompletionSource<string> taskCompletionSource = new TaskCompletionSource<string>();
await Task.Run(() =>
{
try
{
try
{
WebResponse
response
= request.GetResponse();
Stream responseStream = response.GetResponseStream();
string result = new StreamReader(responseStream).ReadToEnd();
taskCompletionSource.SetResult(result);
}
catch (Excecption ex)
{
taskCompletionSource.SetException(ex);
}
}
catch (Excecption ex)
{
taskCompletionSource.SetException(ex);
}
});
return
await taskCompletionSource.Task;
}
Use above
created new async method as follows:
static internal Task<string> GetStringExplictAsync()
{
HttpWebRequest request = HttpWebRequest.Create(@"http://rss.news.yahoo.com/rss/entertainment")
as HttpWebRequest;
return
request.GetStringAsyncExtesion();
}
Pl. Provide your comments on this post.