C#async-どのように機能しますか?
-
27-09-2019 - |
質問
マイクロソフトはそれを発表しました Visual Studio Async CTP 今日(2010年10月28日) async
と await
非同期メソッド実行のためのC#/VBへのキーワード。
最初に、コンパイラがキーワードをスレッドの作成に翻訳するが、 白書 そしてアンダース・ヘジルバーグ PDCプレゼンテーション (31:00)非同期操作はメインスレッドで完全に発生します。
同じスレッドで並行して操作を実行するにはどうすればよいですか?技術的にどのように可能であり、実際にILで翻訳されている機能は何ですか?
解決
同様に機能します 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#で以前に非同期プログラミングを実装することができました。私が書いた それについての記事 少し前 - そして、それはまだ翻訳がどのように機能するかについての洞察をあなたに与えることができると思います。
他のヒント
同じスレッドで並行して操作を実行するにはどうすればよいですか?
できません。 非同期は「並列性」または「並行性」ではありません. 。非同期は並列処理で実装されるか、そうでない可能性があります。作業を小さなチャンクに分割し、各作業の塊をキューに置き、スレッドが他に何もしていないときはいつでも、各作業の塊を実行することによって実装される可能性があります。
私のブログには、これらすべてがどのように機能するかについての一連の記事があります。この質問に直接密接に関係するものは、おそらく来週の木曜日に上昇するでしょう。時計
http://blogs.msdn.com/b/ericlippert/archive/tags/async/
詳細については。
私が理解しているように、何 async
と await
キーワードは、毎回 async
メソッドを使用します await
キーワード、コンパイラは、メソッドの残りの部分を、非同期操作が完了したときにスケジュールされる継続に変えます。それは許可されます async
すぐに発信者に戻り、非同期部品が完了したときに動作を再開する方法。
利用可能な論文によると、それには多くの詳細がありますが、私が間違っていない限り、それが要点です。
私が見るように、非同期の方法の目的は、並行して多くのコードを実行することではなく、必要に応じて呼び出すことができる多くの小さなチャンクに非同期のメソッドを切り刻むことです。重要なポイントは、コンパイラがタスク/継続を使用してコールバックのすべての複雑な配線を処理することです。これにより、複雑さが軽減されるだけでなく、非同期メソッドを従来の同期コードと同様に記述することができます。