私はAsyncCTPを試していて、かなり気に入っています。しかし、ホワイトペーパーからそれを説明する質問がありました。その中で、それは言います:
(ホワイトペーパーにリストされているメソッドの例)のような非同期メソッドは、独自のスレッドでは実行されないことを理解することが重要です。
それらが独自のスレッドで実行されない場合、非同期動作はどのように機能しますか?(たとえば)UIと「await」キーワードが作成するタスクの間で既存のスレッドに多くのコンテキストスイッチがありますか?
私はAsyncCTPを試していて、かなり気に入っています。しかし、ホワイトペーパーからそれを説明する質問がありました。その中で、それは言います:
(ホワイトペーパーにリストされているメソッドの例)のような非同期メソッドは、独自のスレッドでは実行されないことを理解することが重要です。
それらが独自のスレッドで実行されない場合、非同期動作はどのように機能しますか?(たとえば)UIと「await」キーワードが作成するタスクの間で既存のスレッドに多くのコンテキストスイッチがありますか?
asyncメソッドを呼び出すと、最初は同期します。待機するまで非同期になる可能性すらありません。
各await式で、GetAwaiter()
あなたが待っているawaitableで呼び出されます。次に、IsCompleted
プロパティはウェイターでテストされます。タスクがすでに完了している場合、メソッドは同期を続けます。
それ以外の場合は、OnCompleted
メソッドが待機者で呼び出され、継続が追加されます。継続は、タスクが終了したときにコールバックされます。asyncメソッド自体は、まだ完了していないawait式に最初にヒットしたときに呼び出し元に戻ります。
これのスレッド化の正確な性質は、関係する待機者によって異なりますが、の非同期CTPTask<T>
では、TaskAwaiter
は現在のタスクスケジューラを使用して継続をスケジュールします。WinForms / Silverlight / WPFの場合、つまり、UIスレッドで非同期メソッドを開始すると、UIスレッドで続行されます。それ以外の場合(たとえば、すでにスレッドプールスレッドを使用している場合、またはコンソールアプリからこれを使用している場合)、継続はスレッドプールスレッドで実行されます。もちろん、本当に必要な場合は、現在のタスクスケジューラを自分で変更できます。
同様に、異なる待機者は、を使用して継続をスケジュールする必要はありませんTaskScheduler.Current
。たとえば、私のコルーチンの継続は、基本的に実行する継続のキューを保持し、実行されるまで継続します。私のComeFromの継続は、さらに奇妙なものになってしまいます:)
非同期機能が内部でどのように機能するかについての詳細は、それをかなり深く掘り下げている私のEduasyncブログシリーズを読んでください。
この機能を一般的に楽しんでいただければ幸いです...非常にエキサイティングだと思います。
asyncメソッドの背後にある考え方は、実行にスレッドを必要とせず、非同期操作フローの呼び出しと完了の結合を線形に行うだけであるということです。つまり、非同期メソッドを使用してファイルから読み取る場合、読み取りされたファイルの開始部分を同期的に呼び出し、OSレベルの操作が完了して完了を呼び出すまで、実行が一時停止されます(つまり、現在のスレッドを放棄して他の操作を実行します)。提供されます。これにより、残りの非同期メソッドの一時停止が解除されます(少なくとも次の待機まで)。