0

我有如下设置:

class mytype
{
   Awaiter GetAwaiter() { ... }
}

class Awaiter : INotifyCompletion
{
  bool IsCompleted { get { return false; } }
  void GetResult () { }

  void OnCompleted(Action continuation)
  {
    //that's the continuation in focus
  }
}

//somewhere else:
async Task MyMethod()
{
  //here instructions for 1st state 
  await new mytype();
  //here instructions for 2nd state 
  await new mytype();
  //here instructions for 3rd state 
}

我是不是弄错了,或者我从 CLR 获得的委托(在同一个方法中)总是或多或少是同一个委托,但我正在等待的实例是不同的?由于 async 关键字,C# 编译器将 MyMethod 转换为具有 3 个状态的 FSM。每次我在 C# 中等待该方法中的某些内容时,都会在内部调用 FSM 的 MoveNext 方法。但是 FSM 自己跟踪状态,因此它知道它所处的最后一个状态,因此它可以进入下一个状态(并执行与新状态相关的指令)。

因此,基本上我理解,内部名为continuation的委托的调用归结为适当 FSM 类型的 MoveNext 方法的调用。似乎没有什么大魔法——还是我弄错了?

4

1 回答 1

1

是的,你的理解是对的。“大魔法”发生在编译器必须重写MyMethod()到状态机时,而不是在运行时。

有关状态机的外观及其工作原理的更多信息,请阅读 Jon Skeet 的文章从他的 Eduasync 系列中的简单异步方法生成的代码。那篇文章描述了由其中一个 Async CTP 生成的代码,后续文章介绍了此后的更改:Async CTP 和 Visual Studio 11 预览版之间的更改以及 VS11 预览版和 Visual Studio 11 Beta 之间的更改

于 2013-01-24T10:46:59.903 回答