在C#5.0中标记方法异步的后果是什么?

时间:2013-10-12 16:05:36

标签: c# asynchronous async-await c#-5.0

根据我的理解,为了使用await,我必须在一个标记为async的方法中。如果是这种情况,我可以在任何await上使用Task<Thing>稍微同步检索Task结果的值。

Task<bool> task = new Task<bool>(() => false);
task.Start();

int result = await task;

要做到这一点,我需要在标有async的方法内部。

我想问的是async究竟是什么含义以及使用async标记方法的后果是什么。

另外,这两者有什么区别?

Task<bool> Foo() {
  var task = new Task<bool>(() => false);
  task.Start();
  return task;
}

async Task<bool> Foo2() {
  var task = new Task<bool>(() => false);
  task.Start();
  return await task;
}

我可以在await方法中使用async

var res1 = await Foo();
var res2 = await Foo2();

唯一的区别是Foo2可以在其身体中使用await,而Foo则不能吗?

2 个答案:

答案 0 :(得分:3)

它只是警告编译器该方法可能包含await表达式。这使它能够对方法返回值进行一致性检查。并启用编译器内置的重写逻辑,使其将方法转换为隐藏类。

如果您实际上没有在方法体中使用 await 运算符,则不需要进行此重写,也不需要 async 关键字。如果您仍然使用 async ,那么您将得到一个良性警告(CS1998),指出您的代码可能不是您打算编写的。一个很好的诊断。

答案 1 :(得分:2)

async关键字的主要目的是避免与C#5.0之前使用的代码发生冲突。换句话说,我们可以说保持后备兼容性。

在C#5.0之前,您可以将标识符/类型用作await

void Somemethod()
{
    int await = 5;//identifier
    await myAwait = new await();//type
}

上面的代码在C#5.0之前完全有效(在C#5.0中这也是有效的,除非你在异步方法中使用它),如果将await添加为reserved keyword,会发生什么情况c#5.0?您的代码将无法编译。这将是一个重大改变。

因此,要保持向后兼容性,语言设计者选择将await作为上下文关键字。所以下一个问题出现await将是contextual keyword,但这里的背景是什么?

嗯,有async个关键字,async的存在只启用await关键字。它使编译器也向该方法发出AsyncStateMachineAttribute

我没有谈论async方法的变换方式,假设您已经知道或已经超出了问题的范围。