将基于回调的异步方法转换为可等待任务的最佳方法 [英] Best way to convert callback-based async method to awaitable task

查看:23
本文介绍了将基于回调的异步方法转换为可等待任务的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

转换/包装经典"异步方法的最佳方法是什么?该方法使用回调函数返回(可等待的)任务?

What would be the best way to convert/wrap a "classic" asynchronous method that uses a callback to something that returns a (awaitable) Task?

例如,给定以下方法:

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

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

The only way I know of to wrap this into a method returning a task is:

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

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

     return t.Task;
}

这是实现这一目标的唯一方法吗?

Is this the only way to accomplish this?

有没有办法将 GetStringFromUrl(url,callback) 的调用包装在任务本身中(即调用本身将在任务内部运行而不是同步运行)

And is there a way to wrap the call to GetStringFromUrl(url,callback) in the task itself (i.e. the call itself would run inside the task instead of synchronously)

推荐答案

你的代码简短、易读且高效,所以我不明白你为什么要寻找替代方案,但我想不出什么.我认为你的方法是合理的.

Your code is short, readable and efficient, so I don't understand why are you looking for alternatives, but I can't think of anything. I think your approach is reasonable.

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

I'm also not sure why do you think that the synchronous part is okay in the original version, but you want to avoid it in the Task-based one. If you think the synchronous part might take too long, fix it for both versions of the method.

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

But if you want to run it asynchronously (i.e. on the ThreadPool) only in the Task version, you can use 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;
    });
}

这篇关于将基于回调的异步方法转换为可等待任务的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆