前言 :
WinForm表單的多線程開發,有其特定的寫法。
在非WinForm表單線程外的線程,控制WinForm表單上的對象將會引發錯誤。
網路上可以找到很多種的寫法,讓多線程去跨線程式控制制WinForm表單對象。
本章採用匿名函式的方式實作這個功能,以提供不同的選擇。
線程相關資料可以參考 - [Object-oriented] : 線程
範例表單 :
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,幾乎有在很大幅度的進化。
強力推薦對非同步程式設計有興趣的朋友,把整篇文章給看懂。