Showing posts with label .NET. Show all posts
Showing posts with label .NET. Show all posts

Monday, October 05, 2015

Calling Long Running Methods Asynchronously

When you are able to call an async method, do it using async and await or by making your method return a Task:


public async Task<string> RequestData(Uri uri)
{
    WebClient webClient = new WebClient();
    return await webClient.DownloadStringTaskAsync(uri);
} // Rely on underlying Tasks whenever possible.


public Task<string> RequestDataAsync(Uri uri)
{
    WebClient webClient = new WebClient();
    return webClient.DownloadStringTaskAsync(uri);
} // Rely on underlying Tasks whenever possible.

Dealing with synchronous calls

When the method you are calling is not asynchronous, wrap the method in a task delegate:

 
public Task<string> RequestDataAsync(Uri uri)
{
    return Task.Run<string>(
        () =>
        {
            WebClient webClient = new WebClient();
            return webClient.DownloadString(uri);
        });
} // Create Tasks when you have no other choice.


Capturing Exceptions

Getting a little more advanced, what if you might need to capture exceptions from a long running method? Use the following pattern:
 

public Task<string> RequestDataAsync(Uri uri)
{
    var tcs = new TaskCompletionSource<string>();
    WebClient webClient = new WebClient();
    webClient.DownloadStringCompleted +=
        (_, args) =>
        {
            tcs.SetResult(args.Result);
        };
    webClient.DownloadStringAsync(uri);
    return tcs.Task;
} // Example of wrapping Async/Completed.

More info

Async'ing Your Way to a Successful App with .NET
http://channel9.msdn.com/Events/Build/2013/3-301

Creating Async Libraries That Are Modular, Reusable and Fast, in Microsoft Visual C# and Visual Basic
http://channel9.msdn.com/Events/TechEd/Europe/2013/DEV-B318