2016-06-22 6 views

答えて

6

私のブログで説明しているように、long-running I/O operations do not require a thread at all。むしろ、スレッドを必要としない自然に非同期のI/Oを使用します。

デバイスドライバは一般にDMAを使用します。これにより、デバイスはメインシステムRAMから直接読み書きできます。 .NETは、スレッドプールの一部であるIOCP(I/O Completion Port)を使用してこのアプローチを補完し、膨大な数のI/O操作を待つappdomainごとに1つのスレッド(または非常に少数のスレッド)を許可します。

は、あなたの質問の後半、非同期メソッドに答えるために ますリクエストコンテキストと履歴書、それ たり、それがawait前にあった同じスレッド上にないかもしれません。より一般的なシナリオは、I/O操作が完了したときにIOCPに通知します.IOCPは、スレッドプールスレッドを使用してタスクを完了したことなどをマークし、その後、同じスレッドがASP.NETに入りますコンテキストを要求し、ハンドラの実行を再開します。これは ではありません。常にが発生します。スレッドスイッチが必要な場合もありますが、最も一般的なケースです。

+0

ありがとうございますStephen Cleary! – Sunny

+0

I/O操作でない場合はどうなりますか。関数内で実行され、非常に多くの時間を費やすビジネスロジックの場合新しいスレッドを作成しませんか? – Sunny

+0

@サニー:いいえ、 'async'を' await'なしで使うと、コードは単に呼び出しスレッド上で直接実行されます。 'await Task.Run'を使うと、' Task.Run'(*非* async'/'await')は別のスレッドプールスレッドを使います(注:これはASP.NETではお勧めしません)。 –

1

質問に答えるために、すべてのスレッドはスレッドプールから取得されます。

このようなシナリオの例は、サーバーから要求を受け取ったときに、利用可能なスレッドをプールから引き出して要求を処理します。

次に、新しいスレッドを作成します(Asyncまたはその他の手段のいずれか)。新しいスレッドがプールから引き出され、Asyncボディのリクエストが実行されます。

一方、元のスレッドはプールに解放され、別の要求を処理するために戻ります。

スレッドが終了すると、プールから別のスレッド(元のスレッドと同じでない可能性があります)をフェッチして、要求を完了します。

1つのスレッド(同一プールのスレッド)をブロックしているため、このプロセスがCPUにバインドされていると、時間が無駄です。ただし、IOバインド操作はスレッドを使用しないため、このように処理できます。

関連する問題