ベストプラクティスは、async
コールをループ内のコレクションに収集し、Task.WhenAll()
を実行することです。しかし、ループ内でawait
が発生した場合に何が起こるかを知りたい場合は、返されるTask
には何が含まれますか?さらにasync
はどうしますか?新しいタスクを作成し、すでに返されたTask
に順次追加しますか?私が想定ステップは ループ内で、各非同期呼び出しは、タスクの続行を使用して返されたタスクにチェーンされますか?
count
、ループ、条件がLoopAsync
呼び出されるprivate void CallLoopAsync() { var loopReturnedTask = LoopAsync(); } private async Task LoopAsync() { int count = 0; while(count < 5) { await SomeNetworkCallAsync(); count++; } }
以下のコードあたりのよう
SomeNetworkCallAsync
が呼び出され、返されたタスクが待たれています- 新しいタスク/ awaitableが作成された
- 新しいタスクが(
CallLoopAsync
に戻す) 今
、プロセスが生活するのに十分な時間が与えられていれば、どのように/どのようにして、のように次のコード行はなりますcount++
さらにはSomeNetworkCallAsync
を実行しますか?
アップデート - Jon HannaとStephen Clearyに基づいて:
だから一つのタスクがあり、そのタスクの実装はNetworkCallAsyncへ 5の呼び出しを伴うだろうが、ステート・マシンを使用することは、これらのタスクは必要 意味しますこれが機能するためには明示的に連鎖されてはいけません。これは、 の例では、ループ結果を破るかどうかを決定することができます。 タスクの結果などです。
それらが連鎖していないが、各呼び出しは、我々は(状態m/C、awaiter.GetResult();
で)await
を使用していたとして完成する前の呼び出しを待ちます。あたかも5つの連続した呼び出しが行われたように振る舞い、それらは次々に実行されます(の後は、前の呼び出しではは完了しました)。これが本当であるならば、我々はどのように我々は非同期calls.For EXを構成しているにもう少し注意する必要があります:
代わり
private async Task SomeWorkAsync()
{
await SomeIndependentNetworkCall();// 2 sec to complete
var result1 = await GetDataFromNetworkCallAsync(); // 2 sec to complete
await PostDataToNetworkAsync(result1); // 2 sec to complete
}
を書くそれはとても
private Task[] RefactoredSomeWorkAsync()
{
var task1 = SomeIndependentNetworkCall();// 2 sec to complete
var task2 = GetDataFromNetworkCallAsync()
.ContinueWith(result1 => PostDataToNetworkAsync(result1)).Unwrap();// 4 sec to complete
return new[] { task1, task2 };
}
を記述する必要がありますRefactoredSomeWorkAsync
と言うことができるのは、並列処理の可能性があるため、2秒だけ速くなります。
これは間違いありませんか? - はい。 "非同期にすべて"、 "すべての方法を蓄積する"と一緒に、 "が良い方法です。同様の議論はhere
私はOPに説明しようとしている間、私は自分自身を混乱させてしまったことを認めなければなりません。だから私は他のすべてのテキストを削除することに決めました。 –
私の質問は、最初のループの間にコントロールが呼び出し側に返されるため、特に4つのSomeNetworkCallAsync呼び出しのコンテキストで(LoopAsyncの)タスクに何が含まれるかについてです。 – Saravanan