将TPL与现有异步API一起使用

时间:2011-08-09 00:42:39

标签: c# task-parallel-library restsharp

我想将TPL与现有的API一起使用,RestSharp是特定的,所以我可以使用continuation。

但这意味着我必须将不采用传统.NET方法的API包装成异步,而是实现回调。拿一些像这样的代码:

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

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

所以我想在TPL中包装ExecuteAsync,如果可能的话。但我不能为我的生活,弄清楚如何做到这一点。

有什么想法吗?

2 个答案:

答案 0 :(得分:12)

TPL提供TaskCompletionSource类,它允许您将几乎任何内容公开为任务。通过调用SetResultSetException,您可以使任务成功或失败。在您的示例中,您可能会执行以下操作:

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;
}

然后你可以使用它:

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

或者,如果你想链接任务:

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

您可以在http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx

了解有关TaskCompletionSource的更多信息

答案 1 :(得分:1)

在学习TPL时,这对我来说是一个主要的痛点。

您正在寻找的是TaskCompletionSource。当您创建TaskCompletionSource时,它会创建一个特殊的Task对象(可由TaskCompletionSource.Task属性访问),该对象仅在您调用SetResultSetException方法时完成关联TaskCompletionSource

这篇文章解释了how to wrap APM operations with the TPL(以及Rx)。另请参阅this gist演示包含在TPL中的APM操作。