为什么存在async关键字

45
浏览 Channel 9 MSDN 视频时,我发现了以下未回答的评论,希望有人能够解释一下?

我不明白 async 关键字的意义。为什么不允许在任何返回 Task 的方法中使用 await 关键字,就像迭代器可以在任何返回 IEnumerable 的方法上使用 yield return 一样呢?

我相信这里一定有一个好的理由,我只是想了解为什么上述建议不可行。


9
我的蜘蛛感应器在发出警报......Jon Skeet即将到来!在我们等待期间,可以阅读一些更深入的内容:http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx - Adam Houldsworth
1
需要在不同的位置使用两个关键字来实现一个新功能似乎是一个糟糕的设计选择。很多人都在问这个问题,这意味着(对我来说)做出了错误的选择。通过阅读博客中的所有推理,我可以理解逻辑,但妥协并不总是最好的计划。有时候打破一些代码并继续前进会更好。 - adelphus
1
我个人认为做出了最安全的选择。如果防止代码崩溃的唯一障碍是一个简单的关键词,那么这并不是太繁重的任务。人们可能会对此发表意见,但可以假设他们不会遇到向后兼容性问题。很多同意或持中立态度的人并不会表态。 - Adam Houldsworth
4
好的,那么让我们运用科学。你可以创建一个不使用"async"关键字的自己的实现,我们将看到这会引发多少问题。 - Eric Lippert
建议使用编译器选项和 [EnableAwait(true|false)] 属性替换它:http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6518729-don-t-require-async-keyword-for-the-methods-with - artelk
4个回答

25

2
网址似乎有问题?我认为这个是指的:https://learn.microsoft.com/en-us/archive/blogs/ericlippert/asynchrony-in-c-5-part-six-whither-async - Yodiz

15
我觉得也许这篇文章涵盖了推理的原因。

https://learn.microsoft.com/en-us/archive/blogs/ericlippert/asynchrony-in-c-5-part-six-whither-async

第一段陈述:
一些人问我是什么动机决定要求任何包含"await"表达式的方法前缀加上上下文关键字"async"。
它总结道:
这是一大堆利弊;在评估了所有这些利弊之后,并且通过与原型编译器进行大量实验来感受它的效果,C#设计师们决定要求在包含"await"的方法前加上"async"。我认为这是一个合理的选择。
简而言之,这是为了向后兼容性。
进一步阅读:

https://learn.microsoft.com/en-us/archive/blogs/ericlippert/asynchrony-in-c-5-part-one


4
引用Eric Lippert的话几乎就像成为Eric Lippert本人一样好。 - Benjol
9
我想补充一点,我非常希望C# 2的设计者决定在每个想要作为迭代器的方法前加上“iterator”或类似的关键字。必须在解析可能是整个方法体之前才能确定它是否是迭代器块,这让人非常恼火。 - Eric Lippert
1
更不用说它还可以让匿名方法成为迭代器。 - Dax Fohl
Eric Lippert的博客链接已失效。该系列文章的新位置是https://learn.microsoft.com/en-us/archive/blogs/ericlippert/asynchrony-in-c-5-part-one。 - Elroy Flynn
@ElroyFlynn 谢谢你的指正,我已经更新了帖子并附上了你的链接 :-) - Adam Houldsworth

11

对我来说,最有说服力的原因是:当一个函数变成 async 后,return 语句的含义会发生改变。没有 async 时,return x 表示“返回一个值为 x 的任务”,而有了 async 后,则表示“将该任务结果设置为 x”。


3
我曾在博客上写过一篇关于async/await关键字的问题总结
以下是“推断async”部分的结论:
Eric Lippert在这个主题上有权威的文章。它也在博客评论Channel9论坛中讨论过。 简而言之,单词await关键字会造成太大的破坏性变化。选择是在多个单词中等待(例如,await for)或在方法上使用关键字(async),以便仅在该方法中启用await关键字。明确标记方法为async对于人类和计算机来说都更容易解析,因此他们决定使用async/await组合。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接