多くの場合、async-awaitを使用すると、ジョブは別のスレッドによって実行されると考えられることがよくあります。実際、すべての作業は1つのスレッドで行われます。このスレッドは待っているまですべての正常な作業を行います。関数が完了するのを実際に待つのではなく、呼び出し元が何かを持っていることを見るために呼び出しスタックを上がります(呼び出し元が待機していないかどうかを調べるために)、呼び出し元が待たなければならないまで文を実行します。スレッドには、それは完全なコールスタックは、元のawaitがすでに終了している場合、それはチェック待っされるとのawaitなどまで、何かを行うことができますかどうかを確認するためにコールスタックに上がります。そうであればスレッドは待ってからステートメントを続行し、そうでなければスレッドは実際にタスクが終了するまで停止します。
だから限り、どこかのスレッドで、あなたのスレッドではなく、待って、他のことを行うことができ、何のawaitはありません。
private async Task A()
{
Do1();
var taskB = B(); // call B without await
Do2();
await taskB; // wait for B to finish
Do3();
}
private async Task B()
{
Do4();
var taskC = C(); // call C without await
Do5();
await taskC; // wait for C to finish
Do6();
}
private async Task C()
{
Do7();
await Task.Delay(TimeSpan.FromSeconds(0.5));
Do8();
}
A()が呼び出されると、Do1; B; Do4; C; Do7; Task.Delay。スレッドが最初に待機します。
async-awaitのため、スレッドはTask.DelayをCで待機しません。
代わりにスレッドが呼び出しスタックを上って、Bで何かできるかどうかを確認します。この例では、Bはまだ待機していないため、Do5が呼び出されます。今度はBで待っています。スレッドはまだ待機しませんが、プロシージャAへの呼び出しスタックに入り、Aで何かできることがあるかどうかを確認します。実際には、Bを呼び出した後にAが待機していないため、Do2は呼び出される。それからAが待っています。コールスタックの誰もがスレッドを待ってたら、スレッドが戻っTask.Delayに行くと、本当に時間が経過するまで待って起動するなど
、...見てそのコールスタックに上がります。インクルードが待った後、スレッドは、コールスタック内の誰もが待っていることを知っています。
スレッドがDO8を続行し、(それは誰もが待っていたことを知っているすべての後に)C.への呼び出しの後の最初のawaitの後に続けるために、そのコールスタックを上がります。Do6が呼び出され、スレッドはA:Do3で待機した後にステートメントに戻ります。
async-awaitは、プロシージャが呼び出される順序に影響します。したがって、結果が必要な手続きを待つ必要があります。
例でDo2がB()(つまりDo4/Do5/Do6/C/Do7/Do8)で何かの結果を必要とする場合、Do2を呼び出す前にB()を待つべきです。
複数のものが同時に実行されているように見えますが、実際はすべて同じスレッドによって別々に実行されます。
Eric Lippertは、この動作をレストランの料理人:Eric Lippert about async-awaitと比較しました。真ん中のどこかで非同期に検索してください:もしパンが乾杯するまで待つことなく、卵を調理するために水を沸騰させ始める。料理人は同時にトーストパンとトーストのパンにパンを入れませんが、ひとつ待つ代わりにトーストされたパンを必要としない他のことをやり始めます。
私にそれを理解するためにたくさん助けた非同期のawaitの別のリンク:Stephen Cleary about async and await
今すぐ戻ってあなたの質問に。
最初の例では、と書かれています。 このコードでは、UIが明らかにフリーズしています。そして確かにそうです。
2番目の例では、Task.Delayを待つときにスレッドは何もしません。代わりに、それはマウスのクリックに反応するような、何か他のことをすることができるかどうかを知るためにコールステックを上げます。それがUIを生き生きとした状態に保ちます。
ボタンをクリックすると、スレッドはいずれの場合も無限ループに張り付きます。あなたの質問を明確にすることができますか? – Mekap
私の助けてくれてありがとう、最初のケースでは私のアプリはいつも無料で、2番目のケースでは私のアプリが反応し、ラベルは毎秒1秒ごとに更新されました。 – vietvoquoc
何か助けてもらえますか? – vietvoquoc