如果你曾經有過按下一個按鈕執行某一段程式,
或寫入檔案, 又或是讀取某一個網頁,
導致整個UI沒有反應或是無法在進行其他動作時,
這時應該就需要用到非同步的技巧…
以下練習[1]的非同步應用
先拉一個UI如下
private void button1_Click(object sender, EventArgs e)
{
label1.Text = Sum().ToString();
label2.Text = "計算完成";
}
private static long Sum()
{
long sum = 0;
for (int i = 1; i <= 100; i++)
{
sum += i;
}
SpinWait.SpinUntil(() => false, 10000); // 等待10秒
return sum;
}
執行上述程式,的確發生在呼叫Sum副程式後,
整個UI沒有反應@@
------------------------------------------------------------
接下來, 利用 async/await 建立非同步:
方法1: 新增一個task實體, 語法如下
Task<回傳資料型態>(函式名稱)
button2_Click callback function 必須加入async關鍵字在void前, 不然函式中無法呼叫await
private async void button2_Click(object sender, EventArgs e)
{
label1.Text = ""; label2.Text = "";
var taskSum = new Task<long>(Sum);
taskSum.Start();
await taskSum;
label1.Text = taskSum.Result.ToString();
label2.Text = "(1)計算完成";
}
方法2: 利用設計模式 Task.Factory.StartNew
PS. 不建立Task實體
private async void button3_Click(object sender, EventArgs e)
{
label1.Text = ""; label2.Text = "";
var ret = Task.Factory.StartNew<long>(Sum);
label1.Text = ret.Result.ToString();
label2.Text = "(2)計算完成";
}
結論: 個人覺得方法1比較直覺
(1) 新增一個task實體
(2) 啟動該實體(Start)
(3) 接著await該實體
方法2 把await也封裝在Factory裡面, 較(1)更簡單
------------------------------------------------
範例程式:AsyncAwaitApp
參考資料
全站熱搜
留言列表