Asynchronous Programming di C#
Okayy sekarang hari jumat pagi, besok weekend kita bareng-bareng lagi belajar yang rumit-rumit makin weekend makin neraka ngoding dah!. Pada post kali ini saya berasumsi anda sudah bisa basic ngoding,OOP, dan C#.
Sampai saat ini, jujur saya kadang lupa tentang konsep asynchronous programming dan kegunaannya. Saya kadang lupa di C# apa itu Task? await? async? dan lain-lain. Saya masih banyak lihat program dilapangan tidak menggunakan asynchronous programming padahal seharusnya harus menggunakannya. Contoh kasus aplikasi desktop window untuk download data. Proses download data tersebut memerlukan waktu, semakin besar data yang di-download semakin lama waktu yang diperlukan untuk sampai selesai download nya. Karena kita ngodingnya tidak asynchronous UI nya menjadi freeze seperti hang ketika mulai proses download sampai proses download data selesai. Hal ini terjadi karena komputer akan blocking semua kode lainya sampai kode untuk download ini selesai. Menurut saya ini brutal banget dan tidak profesional, kadang saya juga masih suka begitu karena melihat kode lainnya begitu .
Memang kode berantakan atau spaghetti code itu toxic atau beracun bisa merembet dari satu coder ke coder lainya, jadi stop ngoding asal jalan! neraka ngoding banget.
Sekarang kita belajar lagi asynchronous dari sumbernya langsung :
langsung saja belajarnya pake contoh kasus, misal teman-teman sedang menyiapkan sarapan tahapannya sebagai berikut :
- Menuangkan kopi kegelas.
- Panaskan wajan dan goreng telor.
- Goreng sosis (dicontoh aslinya goreng bacon gue ganti jadi goreng sosis biar halal hehe).
- Bakar roti dengan pemanggang.
- Tambahkan mentega dan selai ke roti bakar.
- Menuangkan jus jeruk.
Ini sarapan bule kali yah begini, gue sih biasaya nasi goreng, bubur ayam atau indomie deh. Bayangkan tahapan membuat sarapan diatas dilakukan secara synchronous atau berurutan bakal lama benar.
Berikut analisa kejadian didunia nyata tentang menyiapkan sarapan diatas.
- Menuangkan kopi ke gelas.OK! mungkin tahapan ini memang cepat tidak mungkin menuangkan kopi diwaktu yang sama nyalakan wajan dan goreng telor gpp synchron prosesnya secara alami juga manusia kemungkinan menuangkan kopi tidak berbarengan dengan nyalakan wajan dan goreng sosis.
- Panaskan wajan dan goreng telor. Habis nyalakan wajan dan mulai goreng telor emang diem gituh nungguin telor mateng kenapa ngak sekalian sambil goreng sosis?.
- Tahapan goreng sosis tidak harus menunggu goreng telor selesai. Goreng sosis dimulai sesaat goreng telor dimulai.
- Bakar roti juga dimulai sesaat setelah goreng sosis dimulai tidak harus menunggu goreng sosis selesai.
- Tambahkan selai kemudian tambah mentega ke roti ini proses berurutan biasanya kecuali wadah selai sama mentega dicampur.
- Menuangkan jus jeruk. Tahapan ini mungkin bisa langsung juga tidak harus menunggu roti siap dimakan.
Problemnya ada dua hal kalau kita tetep keukeuh pengen berurutan :
- Waktu menyiapkan sarapan lebih lama.
- Hasil masakannya kurang memuaskan soalnya ada yang keburu dingin.
Berikut adalah kode tahapan menyiapkan sarapan secara synchron. Jangan begini yah ngodingnya!
Setiap baris kode akan dieksekusi olah komputer berurutan. Baris ke-5 tidak akan dieksekusi sebelum baris 3 dan 4 selesai, Baris 7 tidak akan dieksekusi sebelum baris 5 dan 6 selesai begitu seterusnya dan kamu juga yang menyiapkan sarapan beneran diam tidak bisa melakukan yang lain tidak bisa diajak bicara dengan kata lain blocking. Kode diatas kita ganti dengan asynchronous way! yang paling sederhana.
Kode 2 diatas masih mejalankan tahapan menyiapkan sarapan masih berurutan tetapi kamu yang menyiapkannya tidak blocking bisa melakukan yang lain dengan menggunakan keyword await. Kalau tidak menggunakan await seperti kode diatas kamu yang menyiapkan sarapan beneran tunggu satu persatu selesai dan tidak bisa diganggu.
await tugasnya mengeksekusi kode(function) tidak blocking
Kalau masih bingung bayangkan suatu form aplikasi window.
Ada dua button :
- Download : kalau diklik akan menjalankan kode download.
- Exit : kalau diklik akan menutup aplikasi.
Kalau dibelakang button Download kode nya tidak asynchronous ketika diklik form akan freeze kamu tidak bisa klik button Exit langsung kalau terlanjur klik button Download dan ternyata download nya file besar kamu harus menuggu beberapa saat proses download selesai barus bisa klik button Exit dengan kata lain proses download dilakukan di main thread sehingga aplikasi diatas blocking ketika diklik button Download. Sebaliknya kalau kode download nya asynchronous proses download tidak dijalankan di main thread sehingga kapanpun kita mau klik button Exit bisa, walaupun button Download sudah diklik. Apa yang terjadi ketika tombol Download diklik dan kode dibelakannya asynchronous kemudian kita klik Exit langsung? aplikasi akan ketutup download juga batal.
Kode 2 diatas sudah tidak blocking tapi tahapan menyiapkan sarapan masih berurutan kita liat kode 3.
Kode 3 diatas sama seperti Kode 2 tidak blocking masih tetap berurutan belum seperti yang kita inginkan seperti didunia nyata , cuman kita membuat Object Task<tipe object> yang berguna untuk merepresentasikan tugas yang akan dikerjakan. Kode bagian
Task<Toast> toastTask = ToastBread(2);
Toast toast = await toastTask;
ApplyButter(toast);ApplyJam(toast);
Console.WriteLine(“toast is ready”);
Seharusnya bisa disatukan menjadi satu Task menyiapkan roti bakar. Hal tersebut bisa dilakukan dengan cara Komposisi task seperti kode 4.
Kode 4 diatas kalau diperhatikan baris tiga dan empat sebenarnya itu sama dengan baris 3 dan 6 Kode 3. Jenis data var eggsTask adalah Task<Egg> dan Task<Sosis>. Kode 4 masih sama dengan kode 3 masih berurutan dan tidak blocking belum sampai ke kode yang kita inginkan. Kode 4 hanya membuat Task buat roti bakar menjadi satu.
async Task<Toast> MakeToastWithButterAndJamAsync(int number)
{
var toast = await ToastBreadAsync(number); ApplyButter(toast);
ApplyJam(toast);
return toast;
}
Terakhir kode 5 adalah kode yang menurut saya sudah cukup waras lah sesuai skenario dunia nyata.
Berikut adalah penjelasan kode 5
- Kita menuangkan kopi secara singkron
- Kita membuat tugas atau Task-Task : Goreng telor, Goreng sosis, Buat roti bakar pake selai dan mentega
- Jalankan kode task-task satu persatu disaat yang hampir bersamaan tidak saling menunggu. seperti dunia nyata kan? eggTask tidak harus selesai pertama, sosisTask tidak harus selesai kedua dan seterusnya dengan kode
Task finished = await Task.WhenAny(allTasks);
Dengan kode 5 diatas proses menyiapkan sarapan akan lebih cepat dan makanan tidak keburu dingin. gimana sudah jelaskan? masih pusing bagus itu tanda nya ente mikir. Okayyy! sekian dulu sampai jumpa di post neraka ngoding berikutnya. Tetap semangat yow!!! silahkan koreksi teman-teman kalau saya ada salah.