web-dev-qa-db-ja.com

async / awaitを使用すると新しいスレッドが作成されますか?

私は [〜#〜] tpl [〜#〜] が初めてで、疑問に思っています:C#5.0で新しく追加された非同期プログラミングは(新しいasyncawaitキーワード)スレッドの作成に関連しますか?

具体的には、async/awaitを使用すると、使用するたびに新しいスレッドが作成されますか? async/awaitを使用するネストされたメソッドが多数ある場合、それらのメソッドごとに新しいスレッドが作成されますか?

38
dev hedgehog

要するに[〜#〜] no [〜#〜]

から 非同期と待機を使用した非同期プログラミング:スレッド

Asyncおよびawaitキーワードは、追加のスレッドを作成しません。非同期メソッドは独自のスレッドで実行されないため、非同期メソッドはマルチスレッドを必要としません。メソッドは現在の同期コンテキストで実行され、メソッドがアクティブな場合にのみスレッドの時間を使用します。 Task.Runを使用してCPUにバインドされた作業をバックグラウンドスレッドに移動できますが、バックグラウンドスレッドは、結果が利用可能になるのを待っているプロセスには役立ちません。

44
Adriaan Stander

だから私はスレッドモデルを読んでいて、Async/Awaitは確かに新しいスレッドが使用されることにつながる可能性があります(必ずしも作成されない-プールはアプリケーションの起動時にそれらを作成します)。新しいスレッドが必要かどうかを判断するのは、スケジューラ次第です。そして、私が見るように、待機可能な関数の呼び出しには、スケジューラが別のスレッドを利用する可能性を高める内部の詳細が含まれている場合があります。単に仕事が増えると、スケジューラが仕事を分割する機会/理由が増えるからです。

WinRT非同期操作は、スレッドプールで自動的に発生します。そして、通常、UIスレッド作業を除いて、スレッドプールからFROMを呼び出します。Xaml/ Input/Events。

Xaml/UIスレッドで開始された非同期操作の結果は、[呼び出し元] UIスレッドに返されます。ただし、スレッドプールスレッドから開始された非同期操作の結果は、完了した場所に配信されます。これは、以前と同じスレッドではない可能性があります。この背後にある理由は、スレッドプール用に記述されたコードはスレッドセーフになるように記述されている可能性が高く、また効率性のためであり、Windowsはそのスレッドスイッチをネゴシエートする必要はありません。

繰り返しになりますが、OPの答えとして、新しいスレッドは必ずしも作成されませんが、アプリケーションは複数のスレッドを使用して非同期作業を完了することができます。

これはasync/awaitに関する文献のいくつかと矛盾しているように見えますが、それはasync/awaitコンストラクト自体はマルチスレッドではないからです。 Awaitableは、スケジューラが作業を分割し、スレッド間で呼び出しを構築できるメカニズム、またはメカニズムの1つです。

これは非同期とスレッドに関する現在の知識の限界にあるため、正確に正しくないかもしれませんが、待機可能とスレッドの関係を確認することが重要だと思います。

3
Gavin Williams