Meminta harga dari tiga toko secara berurutan memakan waktu jumlah dari ketiganya, padahal ketiga permintaan tidak saling bergantung. Kelas Task menyediakan dua method komposisi untuk situasi ini: Task.WhenAll menunggu sekumpulan task sampai semuanya selesai, dan Task.WhenAny kembali begitu satu task saja selesai lebih dulu. Keduanya menerima task sebagai kelompok, sehingga pemanggil cukup satu await untuk seluruh batch.
Kapan Memakai Yang Mana #
Task.WhenAll: semua hasil dibutuhkan, dan urutan selesainya tidak penting. Hasilnya berupa arrayT[]dengan urutan mengikuti urutan argumen, bukan urutan selesai.Task.WhenAny: hasil pertama sudah cukup, misalnya respons tercepat, atau sebagai dasar timeout dengan task penundaan tambahan.
Kedua method langsung mengembalikan Task, sehingga seluruh batch tetap satu operasi yang dapat ditunggu.
Contoh: Kueri Harga ke Tiga Toko #
Kode berikut menanyakan harga produk ke tiga toko dengan jeda jawaban berbeda, lalu menangkap jawaban pertama dan seluruh jawabannya:
static async Task<int> AmbilHargaAsync(string produk, int jedaMs, int harga)
{
await Task.Delay(jedaMs);
return harga;
}
// Pemanggil:
Task<int> tokoA = AmbilHargaAsync("Kopi Gayo", 50, 95000);
Task<int> tokoB = AmbilHargaAsync("Teh Melati", 150, 30000);
Task<int> tokoC = AmbilHargaAsync("Gula Pasir", 250, 18000);
Task<int> jawabanPertama = await Task.WhenAny(tokoA, tokoB, tokoC);
Console.WriteLine($"Jawaban pertama datang dari: {await jawabanPertama}");
int[] semua = await Task.WhenAll(tokoA, tokoB, tokoC);
Console.WriteLine($"Harga terkumpul: {semua[0]}, {semua[1]}, {semua[2]}");Output yang Dihasilkan:
Jawaban pertama datang dari: 95000
Harga terkumpul: 95000, 30000, 18000Mari kita bedah baris-barisnya:
- Tiga pemanggilan
AmbilHargaAsync: ketiga task dimulai hampir serentak; masing-masing berjalan paralel dengan jeda jawaban 50, 150, dan 250 ms. await Task.WhenAny(...): method kembali saat task toko A selesai, karena jeda 50 ms paling singkat; hasilnya adalah task itu sendiri, bukan nilainya.await jawabanPertama: task pemenang ditunggu sekali lagi untuk mengeluarkan nilai harga 95000.await Task.WhenAll(...): dua task tersisa mungkin sudah selesai saat baris ini berjalan; hasilnya arrayint[]berurutantokoA,tokoB,tokoC, terlepas dari waktu selesai masing-masing.
Bab berikutnya menambahkan sisi kontrol pada pekerjaan paralel ini: cara menghentikan operasi asinkron sebelum selesai menggunakan CancellationToken.