我有一个Base类,它提供了一个带有以下签名的方法:
virtual async Task RunAsync()
Run Code Online (Sandbox Code Playgroud)
派生类应该使用类似的方式覆盖此实现
public override async Task RunAsync()
{
await base.RunAsync();
await this.DoSomethingElse();
}
Run Code Online (Sandbox Code Playgroud)
现在,编译器向我发出警告,指出Base.RunAsync缺少await语句.我希望我的代码是免费警告,而不是抑制警告,并且它运行而不必提供空检查,即使派生类没有提供覆盖实现,因此不能使用virtual Task RunAsync()(省略async关键字).
现在,基本方法中的实现是await Task.Delay(0);解除编译器警告,但在我看来,它在某种程度上并不"干净".应对这个问题的正确方法是什么?
Lua*_*aan 16
你误解了它是如何async运作的.这不是签名的一部分,所以如果你没有需要的await,你实际上并不使用它.因此,即使你提供一个Task RunAsync()方法,你可以只写它没有的async,例如:
virtual Task RunAsync()
{
return Task.FromResult(false);
}
Run Code Online (Sandbox Code Playgroud)
这仍然允许您进行实际使用的覆盖await,如下所示:
override async Task RunAsync()
{
await base.RunAsync();
await DoSomeOtherStuffAsync();
}
Run Code Online (Sandbox Code Playgroud)
这就是编译器为您提供警告的原因 - async关键字完全无用,而不是方法签名的一部分.这只是编译器的一个信号,它允许将标识符await用作关键字,基本上是为了保持与旧C#代码的向后兼容性.
编辑:
正如Jeroen Mostert在评论中所述,从.NET Framework 4.6开始,该Task.CompletedTask属性是公共的,因此您可以这样做:
virtual Task RunAsync()
{
return Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
因此,如果你可以使用4.6+,这是最新,最干净的选择.当然,如果您需要实际返回值的任务,Task.FromResult仍然存在:)
| 归档时间: |
|
| 查看次数: |
6052 次 |
| 最近记录: |