简体   繁体   中英

Using TPL with existing async APIs

I want to use TPL with a existing API, RestSharp to be specific, so I can use continuations.

But this means I have to wrap a API that doesn't take the classical .NET approach to async, but instead implements callbacks. Take some code like this:

var client = new RestClient("service-url");
var request = new RestRequest();

client.ExecuteAsync<List<LiveTileWeatherResponse>>(request, 
    (response) =>
    {
        ...
    });

So here I want to wrap the ExecuteAsync in TPL, if it's possible. But I can't for the life of me, figure out how to do it.

Any ideas?

TPL provides TaskCompletionSource class which allows you to expose pretty much anything as a Task. By calling SetResult or SetException , you can cause the task to succeed or fail. In your example, you could probably do something like:

static Task<T> ExecuteTask<T>(this RestClient client, RestRequest request)
{
    var tcs = new TaskCompletionSource<T>();
    client.ExecuteAsync<T>(request, response => tcs.SetResult(response));
    return tcs.Task;
}

You can then use it:

var task = client.ExecuteTask<List<LiveTileWeatherResponse>>(request);
foreach (var tile in task.Result)
{}

Or, if you want to chain tasks:

var task = client.ExecuteTask<List<LiveTileWeatherResponse>>(request);
task.ContinueWith(
    t => 
    {
        foreach (var tile in t.Result)
        {}
    }
);

You can read more about TaskCompletionSource at http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx

This was a major pain point for me when learning the TPL as well.

What you're looking for is TaskCompletionSource . When you create a TaskCompletionSource , it creates a special Task object (accessible by the TaskCompletionSource.Task property) which only completes when you call the SetResult or SetException methods on the associated TaskCompletionSource .

This post explains how to wrap APM operations with the TPL (and also Rx). See also this gist demonstrating an APM operation wrapped in the TPL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM