将TPL与现有的异步api一起使用
本文关键字:api 一起 异步 TPL | 更新日期: 2023-09-27 18:04:47
我想使用现有API的TPL,具体来说是RestSharp,所以我可以使用延续。
但这意味着我必须包装一个API,它不采用经典的。net方法进行异步,而是实现回调。取一些像这样的代码:
var client = new RestClient("service-url");
var request = new RestRequest();
client.ExecuteAsync<List<LiveTileWeatherResponse>>(request,
(response) =>
{
...
});
如果可能的话,我想在TPL中包装ExecuteAsync。但我无论如何也想不出该怎么做。
任何想法?
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)
{}
}
);
你可以阅读更多关于TaskCompletionSource在http://blogs.msdn.com/b/pfxteam/archive/2009/06/02/9685804.aspx
这也是我学习TPL时的一个主要痛点。
你要找的是TaskCompletionSource
。当你创建一个TaskCompletionSource
时,它会创建一个特殊的Task
对象(通过TaskCompletionSource.Task
属性访问),只有当你在相关的TaskCompletionSource
上调用SetResult
或SetException
方法时才会完成。