開始と待機の違いは何ですか?Stephen Clearyのブログから抜粋した以下のコード(コメントを含む)
public async Task DoOperationsConcurrentlyAsync()
{
Task[] tasks = new Task[3];
tasks[0] = DoOperation0Async();
tasks[1] = DoOperation1Async();
tasks[2] = DoOperation2Async();
// At this point, all three tasks are running at the same time.
// Now, we await them all.
await Task.WhenAll(tasks);
}
タスクはあなたがそれらを待つときに実行を開始すると思いました...しかし、コード内のコメントはそうではないことを暗示しているようです。また、タスクをTask型の配列に関連付けた後、どのようにタスクを実行できますか。それは、本質的に行動を伴わない単なる帰属ではありませんか?
ATask
は「ホット」を返します(つまり、すでに開始されています)。が完了await
するのTask
を非同期的に待機します。
あなたの例では、実際に実行する場所はawait
、タスクを次々に実行するか、すべてを同時に実行するかに影響します。
await DoOperation0Async(); // start DoOperation0Async, wait for completion, then move on
await DoOperation1Async(); // start DoOperation1Async, wait for completion, then move on
await DoOperation2Async(); // start DoOperation2Async, wait for completion, then move on
とは対照的に:
tasks[0] = DoOperation0Async(); // start DoOperation0Async, move on without waiting for completion
tasks[1] = DoOperation1Async(); // start DoOperation1Async, move on without waiting for completion
tasks[2] = DoOperation2Async(); // start DoOperation2Async, move on without waiting for completion
await Task.WhenAll(tasks); // wait for all of them to complete
「この例では(だけでなく)
await
、async
操作を実行しません...同期のように動作しますか?DoOperation0Async()
最初のケースでは他の何かを並行して実行できないため(!)。比較すると、2番目のケースDoOperation0Async()
ではDoOperation1Async()
並行して実行する(例:並行性、async
?の主な利点)」
これは大きなテーマであり、タスクの開始と待機の違いに関する元の質問とは異なるため、SOに関する独自のスレッドであるため、尋ねる価値のある質問です。したがって、この回答は短くし、必要に応じて他の回答を参照します。 。
いいえ、await
INGのasync
操作することは、同期のように振る舞うことはありません。これらのキーワードが行うことは、開発者が同期ワークフローに似た非同期コードを記述できるようにすることです(詳細については、Eric Lippertによるこの回答を参照してください)。
呼び出しawait DoOperation0Async()
は、このコードフローを実行するスレッドをブロックしませんが、の同期バージョンDoOperation0
(またはのようなものDoOperation0Async.Result
)は、操作が完了するまでスレッドをブロックします。
これについては、Webコンテキストで考えてください。リクエストがサーバーアプリケーションに到着したとしましょう。そのリクエストへの応答を生成する一環として、長時間実行される操作を実行する必要があります(たとえば、外部APIにクエリを実行して、応答の生成に必要な値を取得します)。この長時間実行操作の実行が同期している場合、リクエストを実行しているスレッドはブロックします長時間実行される操作が完了するまで待機する必要があるためです。一方、この長時間実行操作の実行が非同期の場合、要求スレッドを解放して、長時間実行操作の実行中に他のこと(他の要求の処理など)を実行できるようにすることができます。次に、長時間実行操作が最終的に完了すると、要求スレッド(またはスレッドプールからの別のスレッド)が中断したところから再開できます(長時間実行操作が完了し、その結果が利用可能になるため) )そして、応答を生成するために残された作業を実行します。
サーバーアプリケーションの例では、async
- async
/のawait
主な利点についての質問の2番目の部分も取り上げています。これは、スレッドの解放に関するものです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加