你能改变一个" async-keyword异步"函数转换为"非异步关键字异步"一个?

时间:2017-10-27 00:03:37

标签: c# asynchronous async-await

想象一下,在代码的某些其他部分或第三方库中定义了以下函数:

public async Task<int> MyAsync()

是否可以将其转换为完全相同的函数,但只是缺少async关键字?例如:

public Task<int> MyAsync2()
{
    ...
    var res = MyAsync();
    ...
 }

基本上,我想要这个功能:

public async Task Foo()
{
    var i = await MyAsync();
    ...
}

和这个功能:

public async Task Foo2()
{
    var i = await MyAsync2();
    ...
}

使具有完全相同的运行时行为。如果MyAsync使用当前上下文(例如UI上下文)执行异步代码,则MyAsync2也应如此。这两者应该是可以互换的。

这可能吗?

2 个答案:

答案 0 :(得分:2)

public Task<int> MyAsync2()
{
    return MyAsync();
}

但是我不明白为什么你需要它:async修饰符是一个实现细节,它不会改变方法的API。例如,如果MyAsync正在实现某个接口,那么接口将是

public interface MyInterface
{
    Task<int> MyAsync();
}

答案 1 :(得分:0)

有可能按照自己的方式行事,但让MyAsync2()方法返回任务而不将其标记为异步有什么意义呢?

我还注意到在MyAsync2()方法中,你可以同步调用MyAsync()。

var res = MyAsync();

请注意,res变量的类型是Task。要在不阻塞当前线程的情况下从任务中获取结果,请使用await:

var res = await MyAsync();

但是,如果你在方法体内使用await关键字,你的MyAsync2()方法应该用async关键字标记,除非你等待任务同步完成,这是不推荐的:

var res = MyAsync();
var result = res.Result;
// or => var result = MyAsync().Result; 

所以,我的答案在语法上是可能的,但在语义上没有必要这样做,更糟糕的是它可能导致一个微妙的错误,例如启动异步任务运行并忘记。