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 から取得したデリゲート (同じメソッド内) は常に多かれ少なかれ同じデリゲートですが、待っているインスタンスは異なりますか? C# コンパイラは、async キーワードのために MyMethod を 3 つの状態を持つ FSM に変換します。そして、C# のメソッドで何かを待機するたびに、内部的に FSM の MoveNext メソッドが呼び出されます。しかし、FSM は状態自体を追跡しているため、最後の状態を認識しているため、次の状態に進む (そして新しい状態に関連付けられた命令を実行する) ことができます。

したがって、本質的には、継続という名前のデリゲートの Invoke は、適切な FSM-Type の MoveNext メソッドの呼び出しに内部的に帰着することを理解しています。大した魔法ではないように思えます - それとも私は間違っていますか?

4

1 に答える 1

1

ええ、あなたの理解は正しいです。「大きな魔法」は、コンパイラがMyMethod()実行時ではなく、ステートマシンに書き直さなければならないときに発生します。

ステートマシンの外観と動作の詳細については、JonSkeetの記事Eduasyncシリーズの単純な非同期メソッドから生成されたコードを参照してください。その記事では、非同期CTPの1つによって生成されたコードについて説明し、その後の記事では、非同期CTPとVisual Studio 11プレビューの間の変更、およびVS11プレビューとVisualStudio11ベータの間の変更について説明します。

于 2013-01-24T10:46:59.903 に答える