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

原文地址:https://www.cnblogs.com/clark159/p/2205102.html