Console App မှာ အချိန်ကြာတဲ့ အလုပ်တွေ (ဥပမာ - File ဖွင့်ဖတ်တာ၊ အင်တာနက်ကနေ Data ဒေါင်းလုပ်ဆွဲတာ) လုပ်တဲ့အခါ async/await က အရမ်းအရေးပါပါတယ်။
ကျွန်တော်တို့ရဲ့ Console App မှာ async/await အလုပ်လုပ်ပုံကို ရှင်းလင်းတဲ့ ဥပမာနဲ့ ရေးပြပါမယ်။
အရင်ဆုံး ကုဒ်မရေးခင် လက်တွေ့ဘဝ ဥပမာလေးတစ်ခုနဲ့ စဉ်းစားကြည့်ပါမယ်။ မနက်စာ "ကော်ဖီဖျော်တာ" နဲ့ "ပေါင်မုန့်မီးကင်တာ" ကို မြင်ယောင်ကြည့်ပါ။
- Synchronous (ပုံမှန်ရေးနေကျပုံစံ):
- ပေါင်မုန့်ကို မီးကင်စက်ထဲ ထည့်လိုက်တယ်။
- ကျက်တဲ့အထိ မီးကင်စက်ရှေ့မှာ ဘာမှမလုပ်ဘဲ မတ်တပ်ရပ်စောင့်နေတယ်။
- ပေါင်မုန့်ကျက်မှ ကော်ဖီစဖျော်တယ်။
- (ဒါက အချိန်ကုန်ပါတယ်၊ စောင့်နေတဲ့အချိန်မှာ ဘာမှမလုပ်ဖြစ်ပါဘူး)
- Asynchronous (Async/Await ပုံစံ):
- ပေါင်မုန့်ကို မီးကင်စက်ထဲ ထည့်လိုက်တယ်။ (Start Task)
- စက်က အလုပ်လုပ်နေတုန်း ကိုယ်က မစောင့်ဘဲ ကော်ဖီသွားဖျော်လိုက်တယ်။ (Do other work)
- ကော်ဖီဖျော်ပြီးလို့ ပေါင်မုန့်ကျက်တဲ့အချိန်ကျမှ ပေါင်မုန့်ကို ယူလိုက်တယ်။ (Await result)
- (ဒါက အချိန်ကုန်သက်သာပြီး လုပ်ငန်းတွင်ကျယ်ပါတယ်)
ကျွန်တော်တို့ရဲ့ C# Console App မှာ အထက်ပါဖြစ်စဉ်ကို ကုဒ်နဲ့ ရေးပြပါမယ်။ ဒီနေရာမှာ Task.Delay ကို သုံးပါမယ်။ သူက အချိန်ကြာတဲ့ အလုပ်တစ်ခုခု (ဥပမာ - Database ခေါ်တာ) ကို တုပ (Simulate) လုပ်ထားတာပါ။
Note: Task.Delay က Thread.Sleep နဲ့ မတူပါဘူး။ Thread.Sleep က ကွန်ပျူတာရဲ့ Thread ကို လုံးဝရပ်ပစ်လိုက်တာဖြစ်ပြီး၊ Task.Delay ကတော့ Thread ကို မရပ်ဘဲ "ခဏစောင့်မယ်" လို့ ပြောပြီး တခြားအလုပ်တွေ ပေးလုပ်ခိုင်းထားတာပါ။
using System;
using System.Threading.Tasks;
namespace AsyncConsoleApp
{
class Program
{
// Main method ကိုယ်တိုင်က async ဖြစ်ဖို့ လိုအပ်ပါတယ်
static async Task Main(string[] args)
{
Console.WriteLine("မနက်စာ စပြင်ပါမယ်...");
// ၁. ပေါင်မုန့်ကင်တဲ့ Task ကို စလိုက်ပါတယ် (မပြီးသေးပါဘူး)
Task<string> toastTask = ToastBreadAsync();
// ၂. ပေါင်မုန့်ကင်စက် အလုပ်လုပ်နေတုန်း ကြားထဲမှာ ကော်ဖီဖျော်ပါမယ်
// ဒီနေရာမှာ Thread က block မဖြစ်တဲ့အတွက် ကော်ဖီဖျော်တဲ့ကုဒ်ကို ချက်ချင်းလုပ်ပါတယ်
PourCoffee();
// ၃. ကော်ဖီဖျော်ပြီးပြီမို့လို့ ပေါင်မုန့်ကျက်မကျက် စောင့်ပြီး ယူပါမယ်
// await သုံးထားတဲ့အတွက် ဒီနေရာရောက်မှသာ Task ပြီးတာကို စောင့်မှာပါ
string toastResult = await toastTask;
Console.WriteLine(toastResult);
Console.WriteLine("မနက်စာ အဆင်သင့်ဖြစ်ပါပြီ!");
Console.ReadLine();
}
// Async method ဖန်တီးပါမယ်
static async Task<string> ToastBreadAsync()
{
Console.WriteLine("ပေါင်မုန့်ကင်စက် ခလုတ်နှိပ်လိုက်ပါပြီ...");
// ၃ စက္ကန့်ကြာမယ့် အလုပ်ကို တုပထားပါတယ်
await Task.Delay(3000);
return "ပေါင်မုန့် ကျက်ပါပြီ!";
}
// ဒါကတော့ ပုံမှန် method ပါ
static void PourCoffee()
{
Console.WriteLine("ကော်ဖီ ဖျော်နေပါပြီ...");
}
}
}- async Task Main:
အရင်တုန်းက Console App တွေမှာ static void Main လို့ သုံးခဲ့ပေမယ့်၊ await ကို သုံးချင်ရင်တော့ Main method ကို async Task ပြောင်းပေးဖို့ လိုအပ်ပါတယ်။
- ToastBreadAsync Method:
ဒီ method နာမည်နောက်မှာ Async ဆိုတဲ့ စာလုံး ထည့်လေ့ရှိတာက C# developer တွေရဲ့ အလေ့အထ (Convention) တစ်ခုပါ။ ဒီ method ထဲမှာ await Task.Delay(3000) ကို တွေ့ပါလိမ့်မယ်။ ဆိုလိုတာက ဒီ method က ၃ စက္ကန့် ကြာမယ်၊ ဒါပေမဲ့ စောင့်နေတဲ့ ၃ စက္ကန့်အတွင်းမှာ ကွန်ပျူတာကြီး ဟန်း (Hang) မသွားဘဲ တခြားအလုပ် (ကော်ဖီဖျော်တာ) ကို လုပ်ခွင့်ပေးလိုက်တာပါ။
- Execution Flow:
ကုဒ်ကို run ကြည့်လိုက်ရင် အောက်ပါအတိုင်း တွေ့ရပါမယ် -
- "ပေါင်မုန့်ကင်စက် ခလုတ်နှိပ်လိုက်ပါပြီ..." (Task စပြီ)
- "ကော်ဖီ ဖျော်နေပါပြီ..." (စောင့်မနေဘဲ ချက်ချင်းလုပ်တယ်)
- (၃ စက္ကန့်ကြာပြီးမှ) -> "ပေါင်မုန့် ကျက်ပါပြီ!" (Task ပြီးမှ ရလာတဲ့ Data)
အခုလောလောဆယ် Console App မှာ မသိသာပေမယ့် နောက်ပိုင်းတွေမှာ Web Development ဘက်ကို ကူးပြောင်းတဲ့အခါ ဒီ concept က အသက်ပါပဲ။
Web Server တစ်ခုမှာ User တွေ အများကြီးက တစ်ပြိုင်နက်ဝင်လာကြမှာပါ။ ကိုယ်က Database ထဲက Data ကို ဆွဲထုတ်နေတုန်း (ပေါင်မုန့်ကင်နေတုန်း) Server ကြီးက ရပ်မနေဘဲ နောက်ထပ်ဝင်လာတဲ့ User (ကော်ဖီဖျော်တာ) ကို လက်ခံဆောင်ရွက်ပေးနိုင်ဖို့အတွက် ဒီ async/await ကို သုံးရခြင်းဖြစ်ပါတယ်။
ကျွန်တော်တို့ရဲ့ Console App လေးကို ကိုယ်တိုင် run ကြည့်ပြီး flow ကို နားလည်အောင် စမ်းသပ်ကြည့်ဖို့ အကြံပြုလိုပါတယ်။