2018年9月12日 星期三

.Net 非同步處理

初次接觸 Windows Form 程式設計時,因為基本觀念不清楚,常常會鬧笑話,以下就是一個常見的例子:
為了避免某段程序執行時無回應,想用另一個 Thread 來處理並回寫資料。(通常是寫入某個元件,例如 Label 或 TextBox,同理讀取資料也是)

看似簡單,但因為 Windows Form 的 UI Thread 是分開的,往往不是只看到最後結果,就是在不同 Thread 內呼叫彼此 UI 元件跳出異常 (跨 Thread 存取 UI 元件是不允許的)。找了一些資料看,程度太差,也是一直半解 Task、Backgroudworker、BeginInvoke、Delegate...

直到發現這篇,寫得非常好:
https://dotblogs.com.tw/johnny/2014/04/02/144594

其中有一段寫到
... 因為上面那三行程式都在同一個 UI thread 上面, 而 Windows Form 會在 UI thread 上的指令執行完畢並且返回之後, 才會觸發它的 Paint 事件。同樣的程式, 如果 ... 在 Console 程式中這個問題就不會發生, 因為 Console 程式沒有像 Windows Form 那種 Paint 事件。

上面的連結寫得很詳細,不再贅述,簡單紀錄一下自己的用法如下:

private async void btnTest_Click(object sender, EventArgs e)
{
    //
    // do something...
    //

    await doSomethingAsync();
}

private async Task doSomethingAsync()
{
    //
    // do something...
    //

    await Task.Delay(1000); // 暫停一下,看效果用
}