async / await。メソッドの待機可能な部分の継続はどこで実行されますか?

ステップアップ

非同期/待機によってプログラムが停止しないようにする方法に本当に興味があります。StephenClearyがasync / awaitを説明する方法が本当に好きです「「await」を「非同期待機」と考えるのが好きです。つまり、asyncメソッドはawaitableが完了するまで(つまり待機するまで)一時停止しますが、実際のスレッドはブロックされません(したがって、非同期です)。」

コンパイラがawaitキーワードに出会うまで、asyncメソッドが同期的に機能することを読みました。上手。コンパイラが待機可能かどうかを判断できない場合、コンパイラは待機可能キューをキューに入れ、メソッドを呼び出したメソッドに制御を譲りますAccessTheWebAsyncOK。呼び出し元(この例ではイベントハンドラー)内で、処理パターンが続行されます。発信者は、その結果をAccessTheWebAsync待つ前に、結果に依存しない他の作業を行う場合や、発信者がすぐに待つ場合があります。イベントハンドラーはを待機してAccessTheWebAsyncおり、AccessTheWebAsyncを待機していGetStringAsyncます。msdnの例をみましょう

async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

msdnブログの別の記事によると、async / awaitは新しいスレッドを作成したり、スレッドプールから他のスレッドを使用したりしませんOK。

私の質問:

  1. async / awaitが待機可能なコードを実行する場所(この例ではWebサイトのダウンロード)により、プログラムのコードの次の行に制御が譲られ、プログラムは結果を尋ねるだけTask<string> getStringTaskですか?新しいスレッドやスレッドプールが使用されていないことはわかっています。

  2. 私は、CLRが現在の実行可能コードとメソッドの待機可能な部分を1つのスレッドのスコープ内で相互に切り替えるだけであるという愚かな仮定に正しいですか?ただし、加数の順序を変更しても合計は変更されず、UIが気付かないうちにブロックされる可能性があります。

スティーブン・クリアリー

async / awaitが待機可能なコードを実行する場所(この例ではWebサイトのダウンロード)により、プログラムのコードの次の行に制御が譲られ、プログラムはタスクgetStringTaskの結果を要求するだけですか?新しいスレッドやスレッドプールが使用されていないことはわかっています。

操作が本当に非同期である場合、「実行」するコードはありません。すべてがコールバックを介して処理されていると考えることができます。HTTPリクエストが(同期的に)送信HttpClientされ、を完了するコールバックが登録されますTask<string>ダウンロードが完了すると、コールバックが呼び出され、タスクが完了します。これより少し複雑ですが、それが一般的な考え方です。

非同期操作をスレッドレスする方法について詳しく説明したブログ投稿があります

私は、CLRが現在の実行可能コードとメソッドの待機可能な部分を1つのスレッドのスコープ内で相互に切り替えるだけだという愚かな仮定に正しいですか?

これは部分的に真のメンタルモデルですが、不完全です。1つには、asyncメソッドが再開するときに、その(以前の)呼び出しスタックが一緒に再開されないことです。したがって、async/await、同様のことを実行するために使用できますがファイバーコルーチンとは大きく異なります

代わりの思考のawait「他のコードへの切り替え」として、「不完全なタスクを返す」と考えます。呼び出し元のメソッドもを呼び出すとawait、不完全なタスクなども返されます。最終的には、不完全なタスクをフレームワーク(ASP.NET MVC / WebAPI / SignalR、または単体テストランナーなど)に返します。または、async voidメソッド(UIイベントハンドラーなど)があります。

操作の進行中に、タスクオブジェクトの「スタック」ができあがります。実際のスタックではなく、依存関係ツリーです。asyncメソッドはタスクインスタンスによって表され、それらはすべてその非同期操作が完了するのを待っています。

メソッドの待機可能な部分の継続はどこで実行されますか?

タスクを待機しているときawait、デフォルトasyncでは、キャプチャされたコンテキストでそのメソッドを再開します。このコンテキストは、そうでSynchronizationContext.Currentない場合はそうでありnull、そうでない場合はTaskScheduler.Currentです。実際には、これはasync、UIスレッドで実行されているメソッドがそのUIスレッドで再開されることを意味します。asyncASP.NET要求を処理するメソッドは、同じASP.NET要求の処理を再開します(おそらく別のスレッドで)。他のほとんどの場合、asyncメソッドはスレッドプールスレッドで再開されます。

質問のサンプルコードでGetStringAsyncは、不完全なタスクが返されます。ダウンロードが完了すると、そのタスクは完了します。そのため、そのダウンロードタスクをAccessTheWebAsync呼び出すawaitと(ダウンロードがまだ完了していないと仮定して)、現在のコンテキストがキャプチャされ、から不完全なタスクが返されAccessTheWebAsyncます。

ダウンロードタスクが完了すると、の継続はAccessTheWebAsyncそのコンテキスト(UIスレッド、ASP.NET要求、スレッドプールなど)にスケジュールされ、そのコンテキストでのLength実行中に結果のを抽出します。ときにAccessTheWebAsyncメソッドが返す、それは以前から返されたタスクの結果を設定しますAccessTheWebAsyncこれにより、次のメソッドなどが再開されます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

async / await。メソッドの待機可能な部分の継続はどこで実行されますか?

分類Dev

Async - Await は別のスレッドで実行されますか?

分類Dev

タスクの継続(async / awaitによって構築された)は、WPFアプリケーションのメインスレッドで実行されていますが、コンソールアプリケーションの子で実行されています

分類Dev

asyncメソッドでawaitがすべての実行を終了するのを待つ方法は?

分類Dev

awaitなしで呼び出されたasyncメソッドのawaitsはまだ非同期ですか?

分類Dev

asyncメソッドのawait呼び出しを完了するまで待機させます

分類Dev

Async / Awaitメソッド-メソッドの実行を待つ必要はありません

分類Dev

ループのこれを停止して待機してから続行するにはどうすればよいですか?(JavaScript async / await with Firestoreリスナー)

分類Dev

Spring @Async Beanメソッドが非同期で実行されないのはなぜですか?

分類Dev

属性のasync / awaitメソッドが返されないのはなぜですか

分類Dev

async / await関数が2回実行されるのはなぜですか?

分類Dev

async / awaitがforEachループ内でioredisgetメソッドの実行を同期しないのはなぜですか?

分類Dev

C# async タスク - メソッドに複数の await() を含めることはできますか

分類Dev

asyncの接尾辞が付いたメソッドでasyncキーワードが使用されないことがあるのはなぜですか?

分類Dev

async / awaitから「進行中」の応答を取得し、それを使用して、待機が完了する前にサーバーが現在実行していることを示すことは可能ですか?

分類Dev

Async Awaitメソッドは、待機ポイントでUIをブロックします

分類Dev

Dartのasync / awaitを使用する場合、メソッドのカスケードは可能ですか?

分類Dev

asyncメソッドの最後の非同期呼び出しは待機する必要がありますか?

分類Dev

async-awaitを使用するメソッドと同等のasync-await-freeとは何ですか?

分類Dev

1つの@Asyncメソッドで使用されるスレッドプールが他の非同期メソッドの実行と共有されます

分類Dev

ES6で「async / await」ステートメントが順次実行されるのと並列に実行されるのはなぜですか?

分類Dev

ES6で「async / await」ステートメントが順次実行されるのと並列に実行されるのはなぜですか?

分類Dev

c#async / await適切な構造で複数のメソッドを同時に実行する

分類Dev

このasync / awaitメソッドの何が問題になっていますか?

分類Dev

c#5.0では、「async / await」関数は実行開始時に常にメインスレッドで実行されますか

分類Dev

module.exportのメソッドでasync / awaitを使用します

分類Dev

Dartのasyncメソッドで「変数が変更されるのを待つ」と書く良い方法はありますか?

分類Dev

std :: asyncはどの程度正確に実行されますか?

分類Dev

'await'演算子は、async>メソッド内でのみ使用できます。

Related 関連記事

  1. 1

    async / await。メソッドの待機可能な部分の継続はどこで実行されますか?

  2. 2

    Async - Await は別のスレッドで実行されますか?

  3. 3

    タスクの継続(async / awaitによって構築された)は、WPFアプリケーションのメインスレッドで実行されていますが、コンソールアプリケーションの子で実行されています

  4. 4

    asyncメソッドでawaitがすべての実行を終了するのを待つ方法は?

  5. 5

    awaitなしで呼び出されたasyncメソッドのawaitsはまだ非同期ですか?

  6. 6

    asyncメソッドのawait呼び出しを完了するまで待機させます

  7. 7

    Async / Awaitメソッド-メソッドの実行を待つ必要はありません

  8. 8

    ループのこれを停止して待機してから続行するにはどうすればよいですか?(JavaScript async / await with Firestoreリスナー)

  9. 9

    Spring @Async Beanメソッドが非同期で実行されないのはなぜですか?

  10. 10

    属性のasync / awaitメソッドが返されないのはなぜですか

  11. 11

    async / await関数が2回実行されるのはなぜですか?

  12. 12

    async / awaitがforEachループ内でioredisgetメソッドの実行を同期しないのはなぜですか?

  13. 13

    C# async タスク - メソッドに複数の await() を含めることはできますか

  14. 14

    asyncの接尾辞が付いたメソッドでasyncキーワードが使用されないことがあるのはなぜですか?

  15. 15

    async / awaitから「進行中」の応答を取得し、それを使用して、待機が完了する前にサーバーが現在実行していることを示すことは可能ですか?

  16. 16

    Async Awaitメソッドは、待機ポイントでUIをブロックします

  17. 17

    Dartのasync / awaitを使用する場合、メソッドのカスケードは可能ですか?

  18. 18

    asyncメソッドの最後の非同期呼び出しは待機する必要がありますか?

  19. 19

    async-awaitを使用するメソッドと同等のasync-await-freeとは何ですか?

  20. 20

    1つの@Asyncメソッドで使用されるスレッドプールが他の非同期メソッドの実行と共有されます

  21. 21

    ES6で「async / await」ステートメントが順次実行されるのと並列に実行されるのはなぜですか?

  22. 22

    ES6で「async / await」ステートメントが順次実行されるのと並列に実行されるのはなぜですか?

  23. 23

    c#async / await適切な構造で複数のメソッドを同時に実行する

  24. 24

    このasync / awaitメソッドの何が問題になっていますか?

  25. 25

    c#5.0では、「async / await」関数は実行開始時に常にメインスレッドで実行されますか

  26. 26

    module.exportのメソッドでasync / awaitを使用します

  27. 27

    Dartのasyncメソッドで「変数が変更されるのを待つ」と書く良い方法はありますか?

  28. 28

    std :: asyncはどの程度正確に実行されますか?

  29. 29

    'await'演算子は、async>メソッド内でのみ使用できます。

ホットタグ

アーカイブ