我想将TPL与现有的API一起使用,RestSharp是特定的,所以我可以使用continuation。
但这意味着我必须将不采用传统.NET方法的API包装成异步,而是实现回调。拿一些像这样的代码:
var client = new RestClient("service-url");
var request = new RestRequest();
client.ExecuteAsync<List<LiveTileWeatherResponse>>(request,
(response) =>
{
...
});
所以我想在TPL中包装ExecuteAsync,如果可能的话。但我不能为我的生活,弄清楚如何做到这一点。
有什么想法吗?
答案 0 :(得分:12)
TPL提供TaskCompletionSource类,它允许您将几乎任何内容公开为任务。通过调用SetResult或SetException,您可以使任务成功或失败。在您的示例中,您可能会执行以下操作:
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
属性访问),该对象仅在您调用SetResult
或SetException
方法时完成关联TaskCompletionSource
。
这篇文章解释了how to wrap APM operations with the TPL(以及Rx)。另请参阅this gist演示包含在TPL中的APM操作。