【发布时间】:2018-01-18 17:36:46
【问题描述】:
假设如下代码:
private async Task Test1Async() => await Task.Delay(1000).ConfigureAwait(false);
private Task Test2Async() => Test1Async();
在功能上,这些函数完全相同,但编译器对调用这些方法的处理不同。以下代码编译,但发出 CS4014 警告:
private void Test() => Test1Async(); // CS4014 is shown
它会生成警告“因为没有等待此调用,所以当前方法在调用完成之前继续运行”。这是一个正确的警告,因为它通常表明您的代码中存在缺陷。如果您真的想要这种行为,那么您可以使用以下代码来解决它:
private void Test() => _ = Test1Async(); // CS4014 is not shown anymore
将值分配给_ 是一项相对较新的功能,表示有意忽略该值。
此代码不会引发 CS4014:
private void Test() => Test2Async(); // CS4014 is not shown!
当然,我可以重写所有方法以使用async/await 方法,但这会导致更多代码运行效率降低(由于async 关键字生成的状态机)。也许我永远不会忘记它,但我的同事可能会然后我不会得到触发器(或者我调用不使用异步的第三方库)。
关于返回的Task使用情况的警告也有所不同。
有谁知道为什么不为返回 Task 且不使用 async 关键字的方法生成此警告?
【问题讨论】:
-
隐藏在语法糖中。该分配确保 Task.Result 属性得到评估。从而确保任务完成。过多的糖确实会导致蛀牙。
-
@HansPassant 哪个 Task.Result 属性?一个简单的任务(非泛型)是否有任何 Result 属性?
-
第二种情况:
Test2Async()没有标记async,所以这个方法本身不认为是“在调用完成前继续[ing]运行” .它确实没有,这个方法在它返回时完全完成。 “继续运行”的是Test1Async()。 -
我的 goolge 似乎坏了,你能告诉我这个
_ = Test1Async()构造的文档/规范的链接吗?这是c#7还是6,我找不到。它有名字吗? -
@RenéVogt:这里提到:blogs.msdn.microsoft.com/dotnet/2017/03/09/…;在页面中搜索“丢弃”。
标签: c# async-await