前言 :
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,几乎有在很大幅度的进化。
强力推荐对异步程序设计有兴趣的朋友,把整篇文章给看懂。