将回调方法转换为任务

问题描述 投票:0回答:1

在C#中,有没有办法转换:

Foo(Action<T> onComplete);

进入:

Task<T> FooTask();

Foo 函数是外部库的一部分,无法修改。

c#
1个回答
4
投票

看起来像是

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.