提问者:小点点

将基于回调的异步方法转换为可等待任务的最佳方法


将使用回调的“经典”异步方法转换/包装为返回(可等待的)任务的东西的最佳方法是什么?

例如,给定以下方法:

public void GetStringFromUrl(string url, Action<string> onCompleted);

我所知道的将其包装到返回任务的方法中的唯一方法是:

public Task<string> GetStringFromUrl(string url)
{
     var t = new TaskCompletionSource<string>();

     GetStringFromUrl(url, s => t.TrySetResult(s));

     return t.Task;
}

这是完成这件事的唯一方法吗?

以及是否有一种方法将对GetStringFromUrl(URLCallback)的调用包装在任务本身中(即调用本身将在任务内部而不是同步地运行)


共2个答案

匿名用户

你的代码简短,可读性强,效率高,所以我不明白你为什么要寻找替代方案,但我什么都想不出来。我认为你的做法是合理的。

我也不知道为什么您认为同步部分在原始版本中还可以,但在

但是如果您只想在版本中异步运行它(即在上),则可以使用:

public Task<string> GetStringFromUrl(string url)
{
    return Task.Run(() =>
    {
        var t = new TaskCompletionSource<string>();

        GetStringFromUrl(url, s => t.TrySetResult(s));

        return t.Task;
    });
}

匿名用户

假设回调只处理成功的情况,那么您所假设的实现就完全可以做到这一点。如果在GetStringFromUrl实现的异步基础中发生异常,当前会发生什么?他们没有真正的方法将其传播到动作回调中。。。他们是不是把它吞了然后把你还给空的还是怎么的?

我唯一推荐的做法是遵循新的惯例,使用XXXAsync后缀来命名这样的异步方法。

相关问题