async / awaitの正確な動作を理解しようとしていますが、頭を包むのに少し問題があります。
この例を考えてみましょう。
public async void StartThread()
{
while(true){
SomeOtherClass.SomeSynchronousStuff();
var something = await SomeOtherClass.SomeOtherAsyncMethod();
}
}
public void ConstructorForThisClass()
{
Thread thread = new Thread(StartThread);
thread.Start();
}
async / awaitについての私の理解は、内部で起こっていることは、コンパイラーが本質的にコードを一連のコールバックに変換し、それぞれの状態オブジェクトを格納しているということです。
したがって、これによると、私の質問は次のとおりです。
SomeOtherAsyncMethod
解放されて他の作業に取り掛かることができますか?SomeOtherAsyncMethod
戻ったときにスレッドプールスレッドが代わりになりますか?StartThread
マネージスレッドではなくスレッドプールスレッドで関数を発行するにはどうすればよいですか?新しく作成されたスレッドは非同期で実行されますか?
あなたの言い回しは少し問題があります。スレッドの作成は完全に同期しています。
つまり、スレッドがSomeOtherAsyncMethodを待機している間、スレッドは解放されて他の作業に取り掛かることができますか?
スレッドThread
プールスレッドではなく、クラスを使用して手動でスレッドを作成しています。AppDomain内では共有されません。それはされます、それは最初のヒット後に解放されawait
たキーワードを、しかし、あなたは無限にそれを使用するため、while
ループ、それはそれ以外の他の作業のために使用されません。
上記が当てはまる場合、SomeOtherAsyncMethodが戻ったときに、スレッドは単に終了し、スレッドプールスレッドが代わりに使用されますか?
前者を無視すると、を使用しないためConfigureAwait(false)
、継続は任意のThreadPoolスレッドで実行されます。しかし、それは本当に文脈に依存します。このデリゲートを新しいスレッドで実行しているので、それが起こります。ただし、たとえば、これをUIスレッドから実行した場合、継続は、関連TaskScheduler
する対応するを介してUIメッセージループにマーシャリングしようとしますSynchronizationContext
。
マネージスレッドではなくスレッドプールスレッドでStartThread関数を発行するにはどうすればよいですか?
Thread
クラスとクラスによって開始されたすべてのスレッドThreadPool
は管理対象スレッドです。「スレッドプールでこのデリゲートを実行するにはどうすればよいですか」という意味の場合、答えは静的クラス経由Task.Run
またはThreadPool
静的クラス経由です。
待機可能なメソッドが呼び出し元に戻ったとき、それを呼び出すスレッドで再開することを強制されますか、それとも任意の空きスレッドが代わりになりますか?
なしConfigureAwait(false)
で実行された場合、それは現在TaskScheduler
およびその基礎となるに強制されSynchronizationContext
ます。これは、UIメッセージループ内で実行し、await
そこで呼び出すと、継続を投稿しようとすることを意味します。TaskScheduler
使用可能なカスタムがない場合は、デフォルトのスレッドプールスケジューラが使用されます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加