yield return
C# 2.0のキーワードと同様に機能します。
非同期メソッドは、実際には通常の順次メソッドではありません。これは、いくつかの状態を持つステート マシン (オブジェクト) にコンパイルされます (ローカル変数はオブジェクトのフィールドに変換されます)。を 2 回使用する間の各コード ブロックはawait
、ステート マシンの 1 つの「ステップ」です。
これは、メソッドが開始されると、最初のステップを実行するだけで、ステート マシンが戻り、実行する作業をスケジュールすることを意味します。作業が完了すると、ステート マシンの次のステップが実行されます。たとえば、このコード:
async Task Demo() {
var v1 = foo();
var v2 = await bar();
more(v1, v2);
}
次のようなものに翻訳されます。
class _Demo {
int _v1, _v2;
int _state = 0;
Task<int> _await1;
public void Step() {
switch(this._state) {
case 0:
this._v1 = foo();
this._await1 = bar();
// When the async operation completes, it will call this method
this._state = 1;
op.SetContinuation(Step);
case 1:
this._v2 = this._await1.Result; // Get the result of the operation
more(this._v1, this._v2);
}
}
重要な部分は、メソッドを使用しSetContinuation
て、操作が完了したときにStep
メソッドを再度呼び出す必要があることを指定することです (メソッドは、フィールドを使用して元のコードの 2 番目のビットを実行する必要があることを認識してい_state
ます)。SetContinuation
は のようなものbtn.Click += Step
で、単一のスレッドで完全に実行されることは容易に想像できます。
C# の非同期プログラミング モデルは、F# の非同期ワークフローに非常に似ており (実際、いくつかの技術的な詳細を除けば、本質的に同じものです)、リアクティブなシングル スレッド GUI アプリケーションを使用して記述することasync
は、非常に興味深い領域です。少なくとも私はそう思います。たとえば、この記事を参照してください(おそらく、今すぐ C# バージョンを作成する必要があります :-))。
変換は反復子 (および) に似てyield return
おり、実際、以前は反復子を使用して C# で非同期プログラミングを実装することができました。しばらく前にそれについての記事を書きましたが、翻訳がどのように機能するかについての洞察を得ることができると思います.