在C#中,有没有办法转换:
Foo(Action<T> onComplete);
进入:
Task<T> FooTask();
Foo 函数是外部库的一部分,无法修改。
TaskCompletionSource
的工作:
Task<T> FooAsync<T>()
{
var tcs = new TaskCompletionSource<T>();
Foo(tcs.SetResult);
return tcs.Task;
}
这允许将基于回调的 API 作为基于
Task
的 API 来使用。
您可以这样打电话:
var result = await FooAsync<YourType>();
SetResult
完成返回的 Task
,并将其 Result
设置为传递到 Foo
回调中的值。
如果
Foo
可以抛出异常,那么应该显式处理并放置在 Task
上(而不是立即抛出),以符合异步约定:
Task<T> FooAsync<T>()
{
var tcs = new TaskCompletionSource<T>();
try
{
Foo(tcs.SetResult);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
return tcs.Task;
}