導入
3件の通信を1件ずつ待つと3倍の時間がかかります。同時に始めてまとめて待つと、全体の待ち時間が大幅に短縮されます。それがTask.WhenAllです。
図解
flowchart TB
subgraph 順番に待つ["逐次: 遅い"]
S1["A待つ"] --> S2["B待つ"] --> S3["C待つ"]
end
subgraph 同時["WhenAll: 速い"]
P1["A"]
P2["B"]
P3["C"]
end
同時 --> DONE["全部終わるのを1回で待つ"]
サンプル
// 3つの Task を「先に始めて」おく(この時点で並行に走り出す)
Task<int> a = FetchAsync(1);
Task<int> b = FetchAsync(2);
Task<int> c = FetchAsync(3);
// WhenAll で全部の完了をまとめて待つ
int[] results = await Task.WhenAll(a, b, c);
Console.WriteLine($"合計: {results.Sum()}"); // 合計: 60
async Task<int> FetchAsync(int id)
{
await Task.Delay(50); // それぞれ50ms。逐次なら150ms、並行なら約50ms
return id * 10;
}
- 先に複数の
Taskを開始しておくと、それらは並行に進む Task.WhenAll(...)で全部の完了をまとめて待つ- 逐次実行より全体の待ち時間が大幅に短縮される
演習
Task<int> t1 = GetAsync(100);
Task<int> t2 = GetAsync(200);
// TODO: t1 と t2 を WhenAll でまとめて待ち、合計を "300" と出力してください
async Task<int> GetAsync(int v) { await Task.Delay(10); return v; }
___
- 期待される出力:
300
ヒント1を見る
int[] r = await Task.WhenAll(t1, t2);
ヒント2を見る
Console.WriteLine(r.Sum());
まとめ
- 複数
Taskを先に開始すると並行に進む Task.WhenAllで全完了をまとめて待つ- 逐次より待ち時間を大幅短縮できる
次回: 重い計算を逃がすTask.Runと、処理を中断するCancellationTokenです。