CS1998"方法缺乏等待运营商"背后的原因是什么?

cpt*_*azz 10 c# asynchronous async-await

async方法缺少任何await运算符时,C#编译器会生成CS1998警告.

警告背后的原因是什么?

我知道async通过添加状态机和异常处理来引入方法的开销.

警告性能的主要原因是什么?或者有理由通知我,我可能已经忘记了await某个地方?

也许来自语言设计团队的人可以对这一个有所了解...... :)

(请:不要发布说'你可以删除async以使警告消失'的答案.我想知道警告背后的原因和决定,而不是解决问题的方法.)

Ste*_*ary 11

警告背后的原因是什么?

简单地说,一种async不使用的await方法几乎肯定是错误的.并非总是错误,否则这将是一个错误.但几乎总是错的,因此警告.

一个令人难以置信的常见异步 - 新手错误就是假设async意味着"使这种方法异步".这通常与"异步"意味着"在后台线程上运行"的假设配对,但有时它只是"魔术"的假设.

因此,警告明确指出代码将同步运行.

我还发现这个警告在重构我自己的代码时很有用 - 有时我最终会得到一个async应该改为同步方法的方法,而这个警告指出了这一点.

如果您有非平凡的(即可能是异常生成的)同步代码并且您需要实现异步方法签名,那么在async没有await用于减少代码的情况下确实如此.在这种情况下,您可以使用async以避免六行TaskCompletionSource<T>try/ catch代码.但这是一个非常小的用例; 在绝大多数情况下,警告是有帮助的.

  • 我会说能够避免`return Task.CompletedTask;`的“极小用例”或需要手动指定`TResult`的场景,因为类型推断在使用`Task时选择了方法返回类型的子类&lt;SuperClass&gt; MyMethodAsync() =&gt; Task.FromResult(subClassValue);`(编译错误,不能将 `Task&lt;SubClass&gt;` 转换为 `Task&lt;SuperClass&gt;`)超过了这个警告的任何好处。我自己通过 `&lt;PropertyGroup&gt;&lt;NoWarn&gt;CS1998&lt;/NoWarn&gt;&lt;/PropertyGroup&gt;` 禁用了这个警告...... (2认同)
  • 为什么在地球上编译器会尝试将某些内容“解释”为“异步新手”?我认为应该只是检查代码并进行编译。而已。还有一个短语“简单地说,不使用await的异步方法几乎肯定是错误的”,没有任何解释。只是一个陈述,甚至没有一个例子。那些“错误”的情况是什么?我仍然不明白为什么这个警告有用。 (2认同)