マイクロソフトは、非同期メソッド実行のためにasync
およびawait
キーワードをC#/ VBに導入する Visual Studio Async CTP 本日(2010年10月28日)を発表しました。
最初に、コンパイラがキーワードをスレッドの作成に変換すると思いましたが、 ホワイトペーパー およびAnders Hejlsbergの PDCプレゼンテーション (31:00)によると非同期操作が発生します完全にメインスレッド上にあります。
同じスレッドで操作を並行して実行するにはどうすればよいですか?それはどのように技術的に可能であり、ILで実際に翻訳された機能は何ですか?
これは、C#2.0のyield return
キーワードと同様に機能します。
非同期方式は、実際には通常の順次方式ではありません。いくつかの状態を持つステートマシン(オブジェクト)にコンパイルされます(ローカル変数はオブジェクトのフィールドに変換されます)。 await
の2つの使用の間のコードの各ブロックは、ステートマシンの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#非同期ワークフローに非常に近く(実際、技術的な詳細を除けば本質的に同じです)、async
を使用してリアクティブなシングルスレッドGUIアプリケーションを作成することは非常に興味深いことです。エリア-少なくとも私はそう思います-たとえばを参照してください この記事 (多分私は今C#バージョンを書くべきです:-))。
変換はイテレーター(およびyield return
)に似ており、実際、イテレーターを使用して以前のC#で非同期プログラミングを実装することができました。私は それについての記事 少し前に書いた-そしてそれはまだあなたに翻訳がどのように機能するかについての洞察を与えることができると思う。
同じスレッドで操作を並行して実行するにはどうすればよいですか?
できません。 非同期は「並列処理」または「並行処理」ではありません。非同期は並列処理で実装される場合とそうでない場合があります。これは、作業を小さなチャンクに分割し、作業の各チャンクをキューに入れ、スレッドが他に何もしていないときはいつでも、作業の各チャンクを実行することによって実装される場合があります。
私のブログには、これらすべてがどのように機能するかについての一連の記事があります。この質問に直接関係するものは、おそらく来週の木曜日に上がるでしょう。見る
http://blogs.msdn.com/b/ericlippert/archive/tags/async/
詳細については。
私が理解しているように、async
およびawait
キーワードが行うことは、async
メソッドがawait
キーワードを使用するたびに、コンパイラーが剰余を変換することです。非同期操作が完了したときにスケジュールされる継続へのメソッドの変換。これにより、async
メソッドはすぐに呼び出し元に戻り、非同期部分が完了したときに作業を再開できます。
入手可能な論文によると、それには多くの詳細がありますが、私が間違っていない限り、それがその要点です。
私が見ているように、非同期メソッドの目的は、多くのコードを並行して実行することではなく、必要に応じて呼び出すことができるいくつかの小さなチャンクに非同期メソッドを分割することです。重要な点は、コンパイラーがタスク/継続を使用してコールバックのすべての複雑な配線を処理することです。これにより、複雑さが軽減されるだけでなく、非同期メソッドを従来の同期コードとほぼ同じように記述できます。