假设我的方法具有void
返回类型,并且我需要await
对此方法中的操作进行操作。
public void someOperation()
{
//dostuff
var res = await someOtherOperation();
//do some other stuff that needs res.
}
当我尝试编译此代码时,我收到错误消息,指出someOperation
必须声明为async
。我不明白为什么。我明白为什么如果该方法有一个返回值,但是当它的void
时没有。或者甚至在等待操作对方法的返回值没有影响的情况下
这已被问及this问题的一部分,但我找不到我想要的答案。 This guy仅提及:
async关键字启用await关键字。所以使用等待的任何方法 必须标记为异步。
async
关键字启用await
关键字的含义。答案 0 :(得分:11)
我不明白为什么。
因为您需要告诉编译器您正在尝试编写异步方法。这正是你引用的文件的意思。
编译器可以推断出你的方法是否包含任何await
表达式 - 但这意味着你可以注释掉一行方法,整个方法的行为会< em>从根本上改变。 (考虑例外处理,例如......)
它还提高了可读性 - 这意味着任何阅读代码的人都知道这是一种异步方法。
基本上,答案是:
答案 1 :(得分:11)
必须将异步方法标记为async
。 async
和await
个关键字配对在一起,主要是出于向后兼容的原因; await
是有效的标识符(不是关键字),因此当它添加到语言中时,他们还添加了async
关键字。
或者,他们可以使用await
的多字关键字,例如await for
。然而,语言设计团队决定采用配对,因为它清楚明确地标记了所有async
方法 - 编译器和人类都更容易解析。
我有一个blog post on the subject,其中包含Eric Lippert's definitive blog post的链接以及blog comments,Channel9 forums,MSDN forums,当然还有right here on Stack Overflow的讨论}。
请注意,没有结果值的async
方法的自然返回类型为Task
,而不是void
。 void
是async
方法的非自然返回类型。因此,当看到“await运算符必须在异步方法中”错误时,您的默认反应应该是标记async
和将返回类型从void
更改为{{1 }}:
Task
这遵循我的MSDN article on the subject中的最佳做法之一:避免public async Task someOperationAsync()
{
//dostuff
var res = await someOtherOperationAsync();
//do some other stuff that needs res.
}
。语言设计者为事件处理程序(或逻辑上的事件处理程序的代码,如async void
)允许 ;任何其他用法都会导致问题。
答案 2 :(得分:0)
因为它们必须在C#中成对使用。这是规则。
“async”关键字在该方法中启用“await”关键字,并更改方法结果的处理方式。这就是async关键字的全部功能!它不会在线程池线程上运行此方法,也不会执行任何其他类型的魔术。 async关键字仅启用await关键字(并管理方法结果)。