Kata kunci async dan await bekerja berpasangan: async menandai method yang memuat titik tunggu, dan await menandai titik tunggu itu sendiri. Banyak pembaca baru menyangka async menjalankan method di thread lain. Kenyataannya, method asinkron tetap berjalan pada thread pemanggil sampai await pertama ditemui; hanya setelah itu eksekusi boleh dipindahkan oleh runtime. Kombinasi keduanya membuat kode asinkron terbaca seperti kode sinkron biasa.
Mekanisme di Balik await #
Ketika compiler menemui method async, compiler membangun state machine dari badan method tersebut. Prosesnya berjalan sebagai berikut:
- Pemanggil memanggil method asinkron; badan method dieksekusi secara sinkron sampai
awaitpertama. awaitmemeriksa task yang ditunggu. Bila task sudah selesai, eksekusi berlanjut langsung ke baris berikutnya.- Bila task belum selesai, method mengembalikan kendali kepada pemanggil, dan sisa badan method didaftarkan sebagai kelanjutan (continuation) yang dijalankan runtime setelah task selesai.
Dari sudut pandang pemanggil, method asinkron hampir selalu mengembalikan Task atau Task<T>, dan pemanggil memilih kapan await dilakukan.
Contoh: Kendali Kembali ke Pemanggil #
Contoh berikut memanggil method asinkron tanpa langsung menunggunya, sehingga terlihat jelas titik di mana kendali kembali:
static async Task ProsesPesananAsync(string nomor)
{
Console.WriteLine($"Pesanan {nomor}: mulai diproses");
await Task.Delay(120);
Console.WriteLine($"Pesanan {nomor}: pembayaran terverifikasi");
}
// Pemanggil:
Task kerja = ProsesPesananAsync("INV-108");
Console.WriteLine("Pemanggil berjalan lagi selama pesanan diproses");
await kerja;
Console.WriteLine("Pemanggil menerima kabar pesanan selesai");Output yang Dihasilkan:
Pesanan INV-108: mulai diproses
Pemanggil berjalan lagi selama pesanan diproses
Pesanan INV-108: pembayaran terverifikasi
Pemanggil menerima kabar pesanan selesaiMari kita bedah urutan kejadiannya:
Task kerja = ProsesPesananAsync("INV-108"): badan method berjalan dan mencetak pesan “mulai diproses”, lalu berhenti diawait Task.Delay(120)dan mengembalikan objekTask.Console.WriteLine("Pemanggil ..."): baris ini dieksekusi sebelum penundaan usai; bukti nyata bahwa kendali telah kembali kepada pemanggil.await kerja: pemanggil menunggu; ketika penundaan usai, kelanjutan method mencetak pesan “pembayaran terverifikasi”.Console.WriteLine("Pemanggil menerima ..."): baris terakhir berjalan setelah task yang ditunggu selesai penuh.
Dengan pemahaman titik tunggu ini, bab berikutnya meninjau pilihan return type untuk method asinkron, termasuk ValueTask<T> yang menghemat alokasi.