繁体   English   中英

async不需要等待的任务方法

[英]async Task method that doesn't need to await

我有一组从基类继承的命令。 基类具有以下声明:

public virtual async Task Execute(object parameter){}

继承类提供了此方法的覆盖,并非所有类都等待任务。 在这些情况下,编译器会生成警告:

这种异步方法缺少“等待”运算符并将同步运行。 考虑使用'await'运算符等待非阻塞API调用,或'await Task.Run(...)'在后台线程上执行CPU绑定工作。

明确提供任务完整返回值是否正确?

public override async Task Execute(object parameter) {
    //code containing no await statements...
    await Task.CompletedTask;
}

您应该避免在重写方法中使用async关键字,这些方法不会await任何事情,而只是返回Task.CompletedTask

public override Task Execute(object parameter) {
    //code containing no await statements...
    return Task.CompletedTask; // or Task.FromResult(0) for older .NET versions
}

这是针对此类“模拟”任务的(少数)用例之一,您可以通过查看有关Task.FromResult 问题来 Task.FromResult 这些注意事项对Task.CompletedTask仍然有效。

作为一个对位, 存在例外情况的处理方式不同。

如果async版本中的同步代码引发异常,则会将该异常直接引发给调用者(对于具有异步签名的方法,这种情况非常罕见)。

如果async版本中的同步代码引发异常,则捕获该异常并将其置于返回的任务上(这是具有异步签名的方法的预期行为)。

因此,如果这样调用方法,则不同的实现将具有不同的异常语义:

var task = Execute(parameter); // non-async exceptions raised here
...
await task; // async exceptions raised here

但是大多数情况下,该方法被调用并立即等待,因此这两个语义合并在一起:

await Execute(parameter); // both async and non-async exceptions raised here

可能无关紧要,但我相信这是一个重要的区别。

如果异常语义对您很重要,那么您确实希望使用async在同步代码周围生成状态机,并且可以在代码中禁用警告:

#pragma warning disable 1998 // use async keyword to capture exceptions
public override async Task Execute(object parameter) {
#pragma warning restore 1998
  //code containing no await statements...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM