Task biasa menjanjikan satu hasil di akhir pekerjaan, padahal banyak sumber data mengirim item satu per satu seiring waktu: sensor suhu gudang melaporkan pembacaan baru setiap beberapa detik, antrean pesanan datang bergelombang, atau API pagination mengirim halaman demi halaman. Async streams adalah fitur C# yang mengisi kebutuhan ini: sebuah urutan item yang setiap itemnya dapat ditunggu secara asinkron. Konsumen membaca urutan itu dengan await foreach, sehingga thread tidak tersita selama menunggu item berikutnya.
Model Data yang Mengalir #
Async streams dibangun di atas dua bagian yang saling melengkapi:
- Produsen mengembalikan
IAsyncEnumerable<T>dan mengirim item denganyield returndi dalam method asinkron; pola penulisannya dibahas tuntas pada bab Async Iterators. - Konsumen menelusuri urutan dengan
await foreach; setiap iterasi menunggu item berikutnya tanpa memblokir thread.
Perbedaan utamanya dengan IEnumerable<T> biasa terletak pada langkah antar item: langkah itu sendiri bisa asinkron, misalnya menunggu jaringan atau timer.
Contoh: Membaca Sensor Suhu Gudang #
Kode berikut menelusuri pembacaan suhu yang dikirim produsen dengan jeda 50 ms per item:
static async IAsyncEnumerable<int> BacaSuhuGudangAsync()
{
for (int i = 1; i <= 3; i++)
{
await Task.Delay(50);
yield return 24 + i;
}
}
// Pemanggil:
await foreach (int suhu in BacaSuhuGudangAsync())
{
Console.WriteLine($"Suhu terbaca: {suhu} derajat");
}
Console.WriteLine("Pembacaan suhu selesai");Output yang Dihasilkan:
Suhu terbaca: 25 derajat
Suhu terbaca: 26 derajat
Suhu terbaca: 27 derajat
Pembacaan suhu selesaiMari kita bedah baris-barisnya:
async IAsyncEnumerable<int>: return type menandakan urutan asinkron; kata kunciasyncwajib karena badan method memuatawait.await Task.Delay(50): produsen menunggu pembacaan sensor berikutnya; selama ini tidak ada thread yang tersita.yield return 24 + i: satu nilai suhu dikirim kepada konsumen, lalu eksekusi produsen menjeda sampai item diminta lagi.await foreach (int suhu in ...): konsumen meminta item berikutnya pada setiap putaran;awaitdi sini menunggu item, bukan sekadar berpindah ke elemen array.Console.WriteLine("Pembacaan suhu selesai"): baris ini berjalan setelah produsen menghabiskan seluruh item.
Bab berikutnya membongkar interface IAsyncEnumerable<T> di balik await foreach, termasuk cara menelusurinya secara manual.