[Windows Forms] 跨執行緒控制WinForm表單物件

[Windows Forms] : 跨執行緒控制WinForm表單物件

 

前言 :

 

WinForm表單的多執行緒開發,有其特定的寫法。
在非WinForm表單執行緒外的執行緒,控制WinForm表單上的物件將會引發錯誤。

 

網路上可以找到很多種的寫法,讓多執行緒去跨執行緒控制WinForm表單物件。
本章採用匿名函式的方式實作這個功能,以提供不同的選擇。

 

 

執行緒相關資料可以參考 - [Object-oriented] : 執行緒

 

 

範例表單 :

 

image

button1 : Button
textBox1 : TextBox

 

範例程式 :

 

private void button1_Click(object sender, EventArgs e)
{
    // 紀錄 WinForm SyncContext
    SynchronizationContext syncContext = SynchronizationContext.Current;

    // 建立 多執行緒要執行的工作
    WaitCallback threadProcDelegate = delegate(object state)
    {
        SendOrPostCallback syncDelegate = null;
            
        // 控制表單 - 通知開始
        syncDelegate = delegate(object stateEx)
        {                   
            MessageBox.Show("多執行緒開始");
            this.textBox1.Text = "多執行緒開始";
        };
        syncContext.Send(syncDelegate, null); // 呼叫 SyncDelegate,執行完畢才往下執行。                
            
        // 執行工作 - 睡個5秒
        Thread.Sleep(5000);

        // 控制表單 - 通知結束
        syncDelegate = delegate(object stateEx)
        {
            MessageBox.Show("多執行緒結束");
            this.textBox1.Text = "多執行緒結束";
        };
        syncContext.Post(syncDelegate, null); // 呼叫 SyncDelegate,呼叫完畢就往下執行。
    };
    ThreadPool.QueueUserWorkItem(threadProcDelegate, null);    
}

threadProcDelegate包起來的部分,代表多執行緒要執行的工作。
syncDelegate包起來的部分,代表多執行緒要控制表單的工作。

 

補充說明 :

 

本篇文章參照的背景技術很多,但是文章內容只保留了實作部分。
有興趣深入研究的朋友,可以參考底下的資料 :

 

1. Anonymous Functions : http://msdn.microsoft.com/zh-tw/library/bb882516.aspx
匿名函式是用來包裝函式成為委派,詳細的內容請參考鏈結內的MSDN資料。
本篇文章主要是使用[匿名方法的Outer變數],來達成簡化不同執行緒內傳送物件的工作。

 

 

2. SynchronizationContext : http://msdn.microsoft.com/zh-tw/library/system.threading.synchronizationcontext(VS.90).aspx
SynchronizationContext 主要是用來處理同步作業。封裝了核心執行緒,用來做多執行緒的同步處理。
WindowsFormsSynchronizationContext是SynchronizationContext的WinForm版實做。

 

 

3. 非同步程式設計模式 : http://msdn.microsoft.com/zh-tw/library/ms228969.aspx
微軟的非同步設計模式從2.0到現在4.0,幾乎有在很大幅度的進化。
強力推薦對非同步程式設計有興趣的朋友,把整篇文章給看懂。

 

期許自己
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。