首页 文章

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

提问于
浏览
59

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

例如,给定以下方法:

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(url,callback)的调用(即调用本身将在任务内运行而不是同步)

2 回答

  • 3

    您的代码简短,易读且高效,因此我不明白您为什么要寻找替代方案,但我无法想到任何事情 . 我认为你的方法是合理的 .

    我也不确定你为什么认为同步部分在原始版本中没问题,但你想在基于 Task 的版本中避免使用它 . 如果您认为同步部件可能需要太长时间,请为该方法的两个版本修复它 .

    但是如果你想仅在 Task 版本中异步运行它(即在 ThreadPool 上),你可以使用Task.Run()

    public Task<string> GetStringFromUrl(string url)
    {
        return Task.Run(() =>
        {
            var t = new TaskCompletionSource<string>();
    
            GetStringFromUrl(url, s => t.TrySetResult(s));
    
            return t.Task;
        });
    }
    
  • 31

    假设回调只能处理成功的情况,那么您假定的实现对此非常好 . 如果在GetStringFromUrl实现的异步基础中发生异常,当前会发生什么?他们没有真正的方法将它传播到Action回调...他们只是吞下它并返回null或者其他东西吗?

    我唯一建议的是使用跟随XXXAsync后缀命名这种异步方法的新约定 .

相关问题