これに遭遇しました post 非同期Webリクエストの作成について説明しています。
単純化はさておき、現実の世界では、非同期要求を作成して次の行でそれを待つだけの場合、最初に同期呼び出しを行うのと同じではありませんか?
番号、 async + await != sync
、継続のため
MSDNから '非同期および待機による非同期プログラミング(C#およびVisual Basic)'
非同期メソッドは、非ブロッキング操作を目的としています。 asyncメソッドのawait式は、待機中のタスクの実行中に現在のスレッドをブロックしません。代わりに、式は継続としてメソッドの残りの部分を登録し、非同期メソッドの呼び出し元に制御を返します。
たとえば、非同期実行はUIスレッドをブロックせず、Some TextBox.Text
はダウンロードが完了した後に更新されます
private async void OnButtonClick()
{
SomeTextBox.Text = await new WebClient().DownloadStringTaskAsync("http://stackoverflow.com/");
}
いいえ、同じではありません。
async
コードブロックはawait
呼び出しが戻るのを待機していますが、アプリケーションの残りの部分は待機していないため、通常どおり続行できます。
対照的に、同期呼び出しでは、コードが実行を完了するまでアプリケーションまたはスレッド全体を待機させ、他の処理を続行します。
Async/awaitに関して明確にさせてください。
Awaitが発生すると、基になるステートマシンにより、制御がすぐに返されます。次に、待機中の呼び出しが完了すると、基礎となる状態マシンにより、待機中の呼び出しの後の行から実行を再開できます。
したがって、非同期ブロックはブロックされず、待機中の呼び出しが完了するのを待機しません。制御は、awaitコマンドが検出されるとすぐに返されます。
基礎となる状態マシンは、使用されず見逃されない非同期/待機の使用の背後にある「魔法」の一部です。
私は同じ質問を念頭に置いてこれにつまずきましたが、回答を読んだ後、質問は「フードの下の魔法」への言及に混同されたようです。
上記の 非同期プログラミング から:
async
キーワードは、メソッドを非同期メソッドに変換します。これにより、本文でawait
キーワードを使用できます。await
キーワードが適用されると、呼び出し元のメソッドが中断され、待機中のタスクが完了するまで、呼び出し元に制御が戻ります。await
は、async
メソッド内でのみ使用できます。
await
を検出したコンテキストはブロックされますか?
残りのアプリケーションブロックをawait
で実行しますか?
それは、アプリケーションの記述方法に依存します。同じコンテキストで順次起動される一連の依存するawait
edタスクの場合(参照: 非同期/待機の動作を理解しようとしています )
await asyncCall1();
await asyncCall2(); // waits for asyncCall1() to complete
このようにして、各await
は次のもののスポーンをブロックします。
一方、並行して起動された同じ依存タスクは並行して実行され、コンテキストは応答時にのみブロックされます。 await
:
Task<int> t1 = asyncCall1();
Task<string> t2 = asyncCall2(); // runs in parallel with asyncCall1()
int val = await t1;
string str = await t2; // waits for asyncCall1() to complete
一般に、await
は、現在のコンテキストが呼び出される外部コンテキストに実行を渡します。ただし、外部コンテキスト自体が現在を待機している場合、それは同じコンテキスト内のシーケンシャルawait
sのようなものです。
したがって、async
のメリットを享受するには、複数の並列コンテキスト(UI、データクライアントなど)を実行するようにアプリケーションを設計する必要があります。次に、1つのコンテキストのawait
が他のコンテキストに実行をもたらすため、アプリケーション全体が個別にブロックされません。 await
。