2017-11-14 3 views
2

誰も私にこれがどういう意味を説明できますか?それは私が尋ねた別のポスト(Does await new Task(async() => Actually halt execution until finished?)での答えだったと私は本当にタスク待ちの電話の誤解

...非同期待機をコメントの一部を理解していないよ - 待つ - 完了するためにタスクを待ち。それはなぜ だと呼ばれる "待っている"。

それは、タスクが完了していないならば、呼び出し元に 戻りを待っているため非同期であり、 タスクが完了した時点でのawaitを次の作業を実行するようにスケジュール になるまで、このスレッドで他の作業を行います。

awaitはタスクに関する演算子であることを理解してください。呼び出しの呼び出し規約は ではありません。待ち受けタイプの表現はすべて が待つことができます。信じているのトラップに落ちることはありません 非同期を呼び出します。呼び出されたメソッドはすでに非同期です。 が返されたタスクが待たれているものです。

「タスクが完了するのを待つ」と同時に「呼び出し元に戻り、他の作業を行う」方法はありますか?

ありがとうございます!

フォローアップ:

私は回答を見てきました

ので、以下の擬似コード例では何が起こるのでしょうか?どのタスクが実際にどのような順序で起こるか?

await new Task(async() => 
{ 
    //Do stuff 1 
    Thread.Sleep(10000); 
} 

EventLog.Write("Do Stuff 2"); 

await new Task(async() => 
{ 
    //Do stuff 3 
    Thread.Sleep(10000); 
} 

"Do It Stuff 1"を実行してから、「Do It Stuff 2」が実行され、「Do Stuff 3」が実行されますか?または、「実行する」を実行し、すぐに「実行する」をクリックし、次に「実行する」を実行しますか?

+0

[新しいタスク(async()=>実際に完了するまで実行を停止しますか?](https://stackoverflow.com/questions/47293580/does-await-new-taskasync-actually-halt-execution)の可能な複製-until-finished) –

+0

"論理的に"待機します。つまり、次の行はタスク完了後にのみ実行されます。 – SLaks

+2

メソッドが部分的に分割されています。 'await'の後の全てのコードは' Continuation'としてスケジュールされているので、すぐに呼び出し元に戻り、 'await'が終了すると' ThreadPool'スレッドか捕捉されたコードの残りの部分が呼び出されます'SynchronizationContext' – JohanP

答えて

3

すべての作業にCPUまたはスレッドが必要なわけではありません。

Webサービスに対してHTTPリクエストを行っているとします。または、ディスクまたはネットワーク上の場所からファイルをストリーミングする。このような場合、要求はネットワークアダプタやディスクコントローラなどの別のハードウェアコンポーネントによって処理されています。

ネットワークに遅延があり、応答を返すのに時間がかかる場合はどうなりますか?あなたはそこに座り、応答を待つことができます。あるいは、他のことをするためにその時間を使うことができます。

これはasyncawaitが本当に便利な場所です。 await I/O(ディスクやネットワークなど)を行う方法では、基本的に「このタスクが完了したら教えてください」と言っています。その後、あなたは他の仕事(おそらくCPUバインド、おそらくI/Oバウンド)を行うことができるように呼び出し元を返します。

待っていたタスクが終了すると、awaitステートメントの後の残りのメソッドが実行されます。これは継続と呼ばれ、ローカルステートはawaitステートメントの時点でキャプチャされ、終了したところでそのまま継続されます。

私が聞いた良い類推は朝食を作ることです。あなたがコーヒーとトーストのカップを持っているとしましょう。湯沸かしは2分かかります。あなたはそこに立って、湯沸かし器が沸騰するのを待ってから、あなたのコーヒーとトーストを作ることができます。または、沸騰の仕事を始めることができ、あなたのトーストを作って、ホイッスリングケトルを聞くと、あなたの「コーヒーを作る」作業は中断したところから続けられます。どちらがより効率的ですか?

あなたの例では

、あなたがこの順序で、次のようになるだろう:

  • は10秒(原料1を実行してください)
  • イベントログへの書き込み(原料2を実行してください)
  • を待って10秒待つ(スタッフ3を行う)

awaitのコールは、それぞれTaskまで続きます。あなたが待っているのは完全です。この場合、asyncTaskを待っているので、実際にはTask<Task>です(非同期の代理人自身がTaskを使用するため)。しかし、私は外側awaitTaskの両方をアンラップし、最も外側のTaskが完了すると継続が予定されていると思います。

+0

実際には答えはありませんが、OPは技術的に待ち望んでいる低レベルのスレッド、メッセージループでどのようなことが起こっているのか尋ねました。 – Fabio

+0

@ファビオ - フォローアップの例に基づいて、私はOPがそれを求めているとは思わない。 – LeopardSkinPillBoxHat

+0

したがって、待ち時間が来るたびにタスクが完了するまで待機します。ありがとう! –

関連する問題