C# 5 Async, Part 3: Preparing Existing code For Await

Posted by Reed on Reed Copsey See other posts from Reed Copsey or by Reed
Published on Tue, 14 Dec 2010 18:25:00 +0000 Indexed on 2011/01/16 20:57 UTC
Read the original article Hit count: 275

Filed under:
|
|
|
|
|
|

While the Visual Studio Async CTP provides a fantastic model for asynchronous programming, it requires code to be implemented in terms of Task and Task<T>.  The CTP adds support for Task-based asynchrony to the .NET Framework methods, and promises to have these implemented directly in the framework in the future.  However, existing code outside the framework will need to be converted to using the Task class prior to being usable via the CTP.

Wrapping existing asynchronous code into a Task or Task<T> is, thankfully, fairly straightforward.  There are two main approaches to this.

Code written using the Asynchronous Programming Model (APM) is very easy to convert to using Task<T>.  The TaskFactory class provides the tools to directly convert APM code into a method returning a Task<T>.  This is done via the FromAsync method.  This method takes the BeginOperation and EndOperation methods, as well as any parameters and state objects as arguments, and returns a Task<T> directly.

For example, we could easily convert the WebRequest BeginGetResponse and EndGetResponse methods into a method which returns a Task<WebResponse> via:

Task<WebResponse> task = Task.Factory
                             .FromAsync<WebResponse>(
                                 request.BeginGetResponse,
                                 request.EndGetResponse,
                                 null);

Event-based Asynchronous Pattern (EAP) code can also be wrapped into a Task<T>, though this requires a bit more effort than the one line of code above.  This is handled via the TaskCompletionSource<T> class.  MSDN provides a detailed example of using this to wrap an EAP operation into a method returning Task<T>.  It demonstrates handling cancellation and exception handling as well as the basic operation of the asynchronous method itself.

The basic form of this operation is typically:

Task<YourResult> GetResultAsync()
{
    var tcs = new TaskCompletionSource<YourResult>();
    // Handle the event, and setup the task results...
    this.GetResultCompleted += (o,e) =>
    {
        if (e.Error != null)
            tcs.TrySetException(e.Error);
       else if (e.Cancelled)
            tcs.TrySetCanceled();
       else
            tcs.TrySetResult(e.Result);
    };

    // Call the asynchronous method
    this.GetResult();

    // Return the task from the TaskCompletionSource
    return tcs.Task;
}

We can easily use these methods to wrap our own code into a method that returns a Task<T>.  Existing libraries which cannot be edited can be extended via Extension methods.  The CTP uses this technique to add appropriate methods throughout the framework.

The suggested naming for these methods is to define these methods as “Task<YourResult> YourClass.YourOperationAsync(…)”.  However, this naming often conflicts with the default naming of the EAP.  If this is the case, the CTP has standardized on using “Task<YourResult> YourClass.YourOperationTaskAsync(…)”.

Once we’ve wrapped all of our existing code into operations that return Task<T>, we can begin investigating how the Async CTP can be used with our own code.

© Reed Copsey or respective owner

Related posts about .NET

Related posts about algorithms