[英]Async and await: Why doesn't an async method whose signature defines a return type of Task explicitly return a Task?
[英]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.