C#后台线程和UI的交互 (转)
  在C#中,从Main()方法开始一个默认的线程,一般称之为主线程,如果在这个进行一些非常耗CPU的计算,那么UI界面就会被挂起而处于假死状态,也就是说无法和用户进行交互了,特别是要用类似进度条来实时显示一些提示信息的时候,这种情况就显得很糟糕。如果多开一些线程来完成一些耗时的计算,那么工作线程也是无法如此更新UI界面中的元素的,比如直接显示一个提示信息:label1.Text=outstring,原因很简单UI属于默认的主线程,而线程间是不能这样直接访问彼此的成员的。
如果要解决以上的两个问题,那么可以借助C#中的Delegate和控件类中的Invoke()方法来搞定。
这里给出的例子比较简单,主要思路是:在Main()中启动其它的线程作为后台进程,其中一个线程是实时显示当前的时间,一个线程是显示一些随机数,这样一来三个线程同时运行,彼此通过代理来联系。
  

 Code
Code
 using System;
using System;
 using System.Drawing;
using System.Drawing;
 using System.Collections;
using System.Collections;
 using System.ComponentModel;
using System.ComponentModel;
 using System.Windows.Forms;
using System.Windows.Forms;
 using System.Data;
using System.Data;
 using System.Threading;
using System.Threading;

 namespace MutliThreadedWinFormsApp
namespace MutliThreadedWinFormsApp


 {
{
 public class Form1 : System.Windows.Forms.Form
    public class Form1 : System.Windows.Forms.Form

 
     {
{
 private Thread currentTimeThread = null;
        private Thread currentTimeThread = null;
 private Thread randomNumbersThread = null;
        private Thread randomNumbersThread = null;
 private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label1;
 private System.Windows.Forms.TextBox currentTime;
        private System.Windows.Forms.TextBox currentTime;
 private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label2;
 private System.Windows.Forms.TextBox randomNumbers;
        private System.Windows.Forms.TextBox randomNumbers;
 private System.Windows.Forms.GroupBox threadManager;
        private System.Windows.Forms.GroupBox threadManager;
 private System.Windows.Forms.Button pause;
        private System.Windows.Forms.Button pause;
 private System.Windows.Forms.Button stop;
        private System.Windows.Forms.Button stop;
 private System.Windows.Forms.Button start;
        private System.Windows.Forms.Button start;
 private System.Windows.Forms.RadioButton manageTime;
        private System.Windows.Forms.RadioButton manageTime;
 private System.Windows.Forms.RadioButton manageNumbers;
        private System.Windows.Forms.RadioButton manageNumbers;
 private System.Windows.Forms.RadioButton manageBoth;
        private System.Windows.Forms.RadioButton manageBoth;
 private System.ComponentModel.Container components = null;
        private System.ComponentModel.Container components = null;

 public Form1()
        public Form1()

 
         {
{
 InitializeComponent();
            InitializeComponent();
 
            
 //创建新的工作线程
            //创建新的工作线程
 currentTimeThread = new Thread(new ThreadStart(CountTime));
            currentTimeThread = new Thread(new ThreadStart(CountTime));
 currentTimeThread.IsBackground = true;
            currentTimeThread.IsBackground = true;
 
            
 randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers));
            randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers));
 randomNumbersThread.IsBackground = true;
            randomNumbersThread.IsBackground = true;
 }
        }

 protected override void Dispose( bool disposing )
        protected override void Dispose( bool disposing )

 
         {
{
 if( disposing )
            if( disposing )

 
             {
{
 if (components != null)
                if (components != null) 

 
                 {
{
 components.Dispose();
                    components.Dispose();
 }
                }
 }
            }
 base.Dispose( disposing );
            base.Dispose( disposing );
 }
        }


 UI设计#region UI设计
        UI设计#region UI设计
 private void InitializeComponent()
        private void InitializeComponent()

 
         {
{
 this.label1 = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
 this.currentTime = new System.Windows.Forms.TextBox();
            this.currentTime = new System.Windows.Forms.TextBox();
 this.label2 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
 this.randomNumbers = new System.Windows.Forms.TextBox();
            this.randomNumbers = new System.Windows.Forms.TextBox();
 this.threadManager = new System.Windows.Forms.GroupBox();
            this.threadManager = new System.Windows.Forms.GroupBox();
 this.manageBoth = new System.Windows.Forms.RadioButton();
            this.manageBoth = new System.Windows.Forms.RadioButton();
 this.manageNumbers = new System.Windows.Forms.RadioButton();
            this.manageNumbers = new System.Windows.Forms.RadioButton();
 this.manageTime = new System.Windows.Forms.RadioButton();
            this.manageTime = new System.Windows.Forms.RadioButton();
 this.pause = new System.Windows.Forms.Button();
            this.pause = new System.Windows.Forms.Button();
 this.stop = new System.Windows.Forms.Button();
            this.stop = new System.Windows.Forms.Button();
 this.start = new System.Windows.Forms.Button();
            this.start = new System.Windows.Forms.Button();
 this.threadManager.SuspendLayout();
            this.threadManager.SuspendLayout();
 this.SuspendLayout();
            this.SuspendLayout();
 //
            // 
 // label1
            // label1
 //
            // 
 this.label1.AutoSize = true;
            this.label1.AutoSize = true;
 this.label1.Location = new System.Drawing.Point(8, 24);
            this.label1.Location = new System.Drawing.Point(8, 24);
 this.label1.Name = "label1";
            this.label1.Name = "label1";
 this.label1.Size = new System.Drawing.Size(79, 13);
            this.label1.Size = new System.Drawing.Size(79, 13);
 this.label1.TabIndex = 0;
            this.label1.TabIndex = 0;
 this.label1.Text = "现在的时间:";
            this.label1.Text = "现在的时间:";
 //
            // 
 // currentTime
            // currentTime
 //
            // 
 this.currentTime.Location = new System.Drawing.Point(88, 23);
            this.currentTime.Location = new System.Drawing.Point(88, 23);
 this.currentTime.Name = "currentTime";
            this.currentTime.Name = "currentTime";
 this.currentTime.ReadOnly = true;
            this.currentTime.ReadOnly = true;
 this.currentTime.Size = new System.Drawing.Size(157, 20);
            this.currentTime.Size = new System.Drawing.Size(157, 20);
 this.currentTime.TabIndex = 1;
            this.currentTime.TabIndex = 1;
 //
            // 
 // label2
            // label2
 //
            // 
 this.label2.AutoSize = true;
            this.label2.AutoSize = true;
 this.label2.Location = new System.Drawing.Point(14, 56);
            this.label2.Location = new System.Drawing.Point(14, 56);
 this.label2.Name = "label2";
            this.label2.Name = "label2";
 this.label2.Size = new System.Drawing.Size(43, 13);
            this.label2.Size = new System.Drawing.Size(43, 13);
 this.label2.TabIndex = 2;
            this.label2.TabIndex = 2;
 this.label2.Text = "随机数";
            this.label2.Text = "随机数";
 //
            // 
 // randomNumbers
            // randomNumbers
 //
            // 
 this.randomNumbers.Location = new System.Drawing.Point(16, 72);
            this.randomNumbers.Location = new System.Drawing.Point(16, 72);
 this.randomNumbers.Name = "randomNumbers";
            this.randomNumbers.Name = "randomNumbers";
 this.randomNumbers.ReadOnly = true;
            this.randomNumbers.ReadOnly = true;
 this.randomNumbers.Size = new System.Drawing.Size(229, 20);
            this.randomNumbers.Size = new System.Drawing.Size(229, 20);
 this.randomNumbers.TabIndex = 3;
            this.randomNumbers.TabIndex = 3;
 //
            // 
 // threadManager
            // threadManager
 //
            // 
 this.threadManager.Controls.Add(this.manageBoth);
            this.threadManager.Controls.Add(this.manageBoth);
 this.threadManager.Controls.Add(this.manageNumbers);
            this.threadManager.Controls.Add(this.manageNumbers);
 this.threadManager.Controls.Add(this.manageTime);
            this.threadManager.Controls.Add(this.manageTime);
 this.threadManager.Controls.Add(this.pause);
            this.threadManager.Controls.Add(this.pause);
 this.threadManager.Controls.Add(this.stop);
            this.threadManager.Controls.Add(this.stop);
 this.threadManager.Controls.Add(this.start);
            this.threadManager.Controls.Add(this.start);
 this.threadManager.Location = new System.Drawing.Point(16, 104);
            this.threadManager.Location = new System.Drawing.Point(16, 104);
 this.threadManager.Name = "threadManager";
            this.threadManager.Name = "threadManager";
 this.threadManager.Size = new System.Drawing.Size(229, 154);
            this.threadManager.Size = new System.Drawing.Size(229, 154);
 this.threadManager.TabIndex = 7;
            this.threadManager.TabIndex = 7;
 this.threadManager.TabStop = false;
            this.threadManager.TabStop = false;
 this.threadManager.Text = "工作线程控制";
            this.threadManager.Text = "工作线程控制";
 //
            // 
 // manageBoth
            // manageBoth
 //
            // 
 this.manageBoth.Location = new System.Drawing.Point(34, 74);
            this.manageBoth.Location = new System.Drawing.Point(34, 74);
 this.manageBoth.Name = "manageBoth";
            this.manageBoth.Name = "manageBoth";
 this.manageBoth.Size = new System.Drawing.Size(104, 16);
            this.manageBoth.Size = new System.Drawing.Size(104, 16);
 this.manageBoth.TabIndex = 12;
            this.manageBoth.TabIndex = 12;
 this.manageBoth.Text = "同时运行";
            this.manageBoth.Text = "同时运行";
 this.manageBoth.CheckedChanged += new System.EventHandler(this.manageBoth_CheckedChanged);
            this.manageBoth.CheckedChanged += new System.EventHandler(this.manageBoth_CheckedChanged);
 //
            // 
 // manageNumbers
            // manageNumbers
 //
            // 
 this.manageNumbers.Location = new System.Drawing.Point(34, 50);
            this.manageNumbers.Location = new System.Drawing.Point(34, 50);
 this.manageNumbers.Name = "manageNumbers";
            this.manageNumbers.Name = "manageNumbers";
 this.manageNumbers.Size = new System.Drawing.Size(104, 16);
            this.manageNumbers.Size = new System.Drawing.Size(104, 16);
 this.manageNumbers.TabIndex = 11;
            this.manageNumbers.TabIndex = 11;
 this.manageNumbers.Text = "更新随机数线程";
            this.manageNumbers.Text = "更新随机数线程";
 this.manageNumbers.CheckedChanged += new System.EventHandler(this.manageNumbers_CheckedChanged);
            this.manageNumbers.CheckedChanged += new System.EventHandler(this.manageNumbers_CheckedChanged);
 //
            // 
 // manageTime
            // manageTime
 //
            // 
 this.manageTime.Location = new System.Drawing.Point(34, 26);
            this.manageTime.Location = new System.Drawing.Point(34, 26);
 this.manageTime.Name = "manageTime";
            this.manageTime.Name = "manageTime";
 this.manageTime.Size = new System.Drawing.Size(104, 16);
            this.manageTime.Size = new System.Drawing.Size(104, 16);
 this.manageTime.TabIndex = 10;
            this.manageTime.TabIndex = 10;
 this.manageTime.Text = "更新时间线程";
            this.manageTime.Text = "更新时间线程";
 this.manageTime.CheckedChanged += new System.EventHandler(this.manageTime_CheckedChanged);
            this.manageTime.CheckedChanged += new System.EventHandler(this.manageTime_CheckedChanged);
 //
            // 
 // pause
            // pause
 //
            // 
 this.pause.Location = new System.Drawing.Point(84, 115);
            this.pause.Location = new System.Drawing.Point(84, 115);
 this.pause.Name = "pause";
            this.pause.Name = "pause";
 this.pause.Size = new System.Drawing.Size(54, 23);
            this.pause.Size = new System.Drawing.Size(54, 23);
 this.pause.TabIndex = 9;
            this.pause.TabIndex = 9;
 this.pause.Text = "暂停";
            this.pause.Text = "暂停";
 this.pause.Click += new System.EventHandler(this.pause_Click);
            this.pause.Click += new System.EventHandler(this.pause_Click);
 //
            // 
 // stop
            // stop
 //
            // 
 this.stop.Location = new System.Drawing.Point(158, 115);
            this.stop.Location = new System.Drawing.Point(158, 115);
 this.stop.Name = "stop";
            this.stop.Name = "stop";
 this.stop.Size = new System.Drawing.Size(51, 23);
            this.stop.Size = new System.Drawing.Size(51, 23);
 this.stop.TabIndex = 8;
            this.stop.TabIndex = 8;
 this.stop.Text = "停止";
            this.stop.Text = "停止";
 this.stop.Click += new System.EventHandler(this.stop_Click);
            this.stop.Click += new System.EventHandler(this.stop_Click);
 //
            // 
 // start
            // start
 //
            // 
 this.start.Location = new System.Drawing.Point(6, 115);
            this.start.Location = new System.Drawing.Point(6, 115);
 this.start.Name = "start";
            this.start.Name = "start";
 this.start.Size = new System.Drawing.Size(50, 23);
            this.start.Size = new System.Drawing.Size(50, 23);
 this.start.TabIndex = 7;
            this.start.TabIndex = 7;
 this.start.Text = "开始";
            this.start.Text = "开始";
 this.start.Click += new System.EventHandler(this.start_Click);
            this.start.Click += new System.EventHandler(this.start_Click);
 //
            // 
 // Form1
            // Form1
 //
            // 
 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
 this.ClientSize = new System.Drawing.Size(253, 271);
            this.ClientSize = new System.Drawing.Size(253, 271);
 this.Controls.Add(this.threadManager);
            this.Controls.Add(this.threadManager);
 this.Controls.Add(this.randomNumbers);
            this.Controls.Add(this.randomNumbers);
 this.Controls.Add(this.label2);
            this.Controls.Add(this.label2);
 this.Controls.Add(this.currentTime);
            this.Controls.Add(this.currentTime);
 this.Controls.Add(this.label1);
            this.Controls.Add(this.label1);
 this.Name = "Form1";
            this.Name = "Form1";
 this.Text = "工作线程和UI的交互";
            this.Text = "工作线程和UI的交互";
 this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
 this.threadManager.ResumeLayout(false);
            this.threadManager.ResumeLayout(false);
 this.ResumeLayout(false);
            this.ResumeLayout(false);
 this.PerformLayout();
            this.PerformLayout();
 }
        }
 #endregion
        #endregion

 
        
 [STAThread]
        [STAThread]
 static void Main()
        static void Main() 

 
         {
{
 Application.Run(new Form1());
            Application.Run(new Form1());
 }
        }

 private void start_Click(object sender, System.EventArgs e)
        private void start_Click(object sender, System.EventArgs e)

 
         {
{
 bool bTime = false, bRandomNumbers = false;
            bool bTime = false, bRandomNumbers = false;

 if( manageTime.Checked || manageBoth.Checked )
            if( manageTime.Checked || manageBoth.Checked )
 bTime = true;
                bTime = true;
 if( manageNumbers.Checked || manageBoth.Checked )
            if( manageNumbers.Checked || manageBoth.Checked )
 bRandomNumbers = true;
                bRandomNumbers = true;

 if( bTime )
            if( bTime )
 currentTimeThread.Start();
                currentTimeThread.Start();
 
            
 if( bRandomNumbers )
            if( bRandomNumbers )
 randomNumbersThread.Start();
                randomNumbersThread.Start();

 start.Enabled = false;
            start.Enabled = false;
 stop.Enabled = true;
            stop.Enabled = true;
 pause.Enabled = true;
            pause.Enabled = true;
 }
        }

 private void stop_Click(object sender, System.EventArgs e)
        private void stop_Click(object sender, System.EventArgs e)

 
         {
{
 bool bTime = false, bRandomNumbers = false;
            bool bTime = false, bRandomNumbers = false;

 if( manageTime.Checked == true || manageBoth.Checked == true )
            if( manageTime.Checked == true || manageBoth.Checked == true )
 bTime = true;
                bTime = true;
 if( manageNumbers.Checked == true || manageBoth.Checked == true )
            if( manageNumbers.Checked == true || manageBoth.Checked == true )
 bRandomNumbers = true;
                bRandomNumbers = true;

 if( bTime )
            if( bTime )

 
             {
{
 currentTimeThread.Abort();
                currentTimeThread.Abort();
 currentTimeThread.Join();
                currentTimeThread.Join();

 currentTimeThread = new Thread(new ThreadStart(CountTime));
                currentTimeThread = new Thread(new ThreadStart(CountTime));
 currentTimeThread.IsBackground = true;
                currentTimeThread.IsBackground = true;
 }
            }

 if( bRandomNumbers )
            if( bRandomNumbers )

 
             {
{
 randomNumbersThread.Abort();
                randomNumbersThread.Abort();
 randomNumbersThread.Join();
                randomNumbersThread.Join();

 randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers));
                randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers));
 randomNumbersThread.IsBackground = true;
                randomNumbersThread.IsBackground = true;
 }
            }

 start.Enabled = true;
            start.Enabled = true;
 stop.Enabled = false;
            stop.Enabled = false;
 pause.Enabled = false;
            pause.Enabled = false;
 }
        }

 private void pause_Click(object sender, System.EventArgs e)
        private void pause_Click(object sender, System.EventArgs e)

 
         {
{
 bool bTime = false, bRandomNumbers = false;
            bool bTime = false, bRandomNumbers = false;

 if( manageTime.Checked == true || manageBoth.Checked == true )
            if( manageTime.Checked == true || manageBoth.Checked == true )
 bTime = true;
                bTime = true;
 if( manageNumbers.Checked == true || manageBoth.Checked == true )
            if( manageNumbers.Checked == true || manageBoth.Checked == true )
 bRandomNumbers = true;
                bRandomNumbers = true;

 if( bTime )
            if( bTime )

 
             {
{
 if( 0 != (currentTimeThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) )
                if( 0 != (currentTimeThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) )
 currentTimeThread.Resume();
                    currentTimeThread.Resume();
 else
                else
 currentTimeThread.Suspend();
                    currentTimeThread.Suspend();
 }
            }


 if( bRandomNumbers )
            if( bRandomNumbers )

 
             {
{
 if( 0 != (randomNumbersThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) )
                if( 0 != (randomNumbersThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) )
 randomNumbersThread.Resume();
                    randomNumbersThread.Resume();
 else
                else
 randomNumbersThread.Suspend();
                    randomNumbersThread.Suspend();
 }
            }
 }
        }

 private void manageTime_CheckedChanged(object sender, System.EventArgs e)
        private void manageTime_CheckedChanged(object sender, System.EventArgs e)

 
         {
{
 }
        }

 private void manageNumbers_CheckedChanged(object sender, System.EventArgs e)
        private void manageNumbers_CheckedChanged(object sender, System.EventArgs e)

 
         {
{
 }
        }

 private void manageBoth_CheckedChanged(object sender, System.EventArgs e)
        private void manageBoth_CheckedChanged(object sender, System.EventArgs e)

 
         {
{
 }
        }


 /**//// <summary>
        /**//// <summary>
 /// 注意其Invoke的使用,其有两种使用形式
        /// 注意其Invoke的使用,其有两种使用形式
 /// public void Invoke(System.Delegate delegate);
        /// public void Invoke(System.Delegate delegate);
 /// public void Invoke(System.Delegate delegate, object [] args);
        /// public void Invoke(System.Delegate delegate, object [] args);
 /// </summary>
        /// </summary>
 public void CountTime()
        public void CountTime()

 
         {
{
 while(true)
            while(true)

 
             {
{
 Invoke(new UpdateTimeDelegate(updateCurrentTime));
                Invoke(new UpdateTimeDelegate(updateCurrentTime));
 Thread.Sleep(1000);
                Thread.Sleep(1000);
 }
            }
 }
        }

 public void GenerateRandomNumbers()
        public void GenerateRandomNumbers()

 
         {
{
 int [] randomNumbers = new int[10];
            int [] randomNumbers = new int[10];
 Random r = new Random();
            Random r = new Random();

 while(true)
            while(true)

 
             {
{
 for(int i = 0; i < randomNumbers.Length; i++)
                for(int i = 0; i < randomNumbers.Length; i++)
 randomNumbers[i] = r.Next(1, 100);
                    randomNumbers[i] = r.Next(1, 100);


 Invoke(new UpdateRandomNumbers(updateRandomNumbers), new object[]
                Invoke(new UpdateRandomNumbers(updateRandomNumbers), new object[]  { randomNumbers });
{ randomNumbers });
 Thread.Sleep(500);
                Thread.Sleep(500);
 }
            }
 }
        }


 /**//// <summary>
        /**//// <summary>
 /// 负责更新UI界面中时间显示的函数
        /// 负责更新UI界面中时间显示的函数
 /// </summary>
        /// </summary>
 private void updateCurrentTime()
        private void updateCurrentTime()

 
         {
{
 currentTime.Text = DateTime.Now.ToLongTimeString();
            currentTime.Text = DateTime.Now.ToLongTimeString();
 }
        }

 
        

 /**//// <summary>
        /**//// <summary>
 /// 负责更新UI界面中随机数显示的函数
        /// 负责更新UI界面中随机数显示的函数
 /// </summary>
        /// </summary>
 /// <param name="numbers"></param>
        /// <param name="numbers"></param>
 private void updateRandomNumbers(int [] numbers)
        private void updateRandomNumbers(int [] numbers)

 
         {
{
 System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Text.StringBuilder sb = new System.Text.StringBuilder();

 foreach(int i in numbers)
            foreach(int i in numbers)
 sb.Append(i.ToString()).Append(", ");
                sb.Append(i.ToString()).Append(", ");

 randomNumbers.Text = sb.ToString();
            randomNumbers.Text = sb.ToString();
 }
        }

 private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)

 
         {
{
 if( (randomNumbersThread.ThreadState & ThreadState.Running) == ThreadState.Running )
            if( (randomNumbersThread.ThreadState & ThreadState.Running) == ThreadState.Running )
 randomNumbersThread.Abort();
                randomNumbersThread.Abort();

 randomNumbersThread = null;
            randomNumbersThread = null;
 
            
 if( (currentTimeThread.ThreadState & ThreadState.Running) == ThreadState.Running )
            if( (currentTimeThread.ThreadState & ThreadState.Running) == ThreadState.Running )
 currentTimeThread.Abort();
                currentTimeThread.Abort();

 currentTimeThread = null;
            currentTimeThread = null;
 }
        }
 }
    }

 public delegate void UpdateTimeDelegate();
    public delegate void UpdateTimeDelegate();
 public delegate void UpdateRandomNumbers(int [] numbers);
    public delegate void UpdateRandomNumbers(int [] numbers);
 }
}
 
其实在C# 2.0 中所有的Control类都有Invoke()方法,如果负责更新UI元素的函数不是定义在Main()中,那么必须首先检测Control类中的InvokeRequired属性。举个例子吧,注意setProgressBarValue()函数中调用自己的方式.
//在工作线程中更新主窗口进度条
public void setProgressBarValue(ProgressBar progressBar1,int value)
{
if (progressBar1.InvokeRequired)
{
object[] parameters = new object[] { value };
progressBar1.Invoke(new setProgressBarValueDelegate(setProgressBarValue), parameters);
}
else
progressBar1.Value = value;
}
这里的一些代码参考了http://www.codeproject.com 的例子.
如果要解决以上的两个问题,那么可以借助C#中的Delegate和控件类中的Invoke()方法来搞定。
这里给出的例子比较简单,主要思路是:在Main()中启动其它的线程作为后台进程,其中一个线程是实时显示当前的时间,一个线程是显示一些随机数,这样一来三个线程同时运行,彼此通过代理来联系。

 Code
Code using System;
using System; using System.Drawing;
using System.Drawing; using System.Collections;
using System.Collections; using System.ComponentModel;
using System.ComponentModel; using System.Windows.Forms;
using System.Windows.Forms; using System.Data;
using System.Data; using System.Threading;
using System.Threading;
 namespace MutliThreadedWinFormsApp
namespace MutliThreadedWinFormsApp

 {
{ public class Form1 : System.Windows.Forms.Form
    public class Form1 : System.Windows.Forms.Form
 
     {
{ private Thread currentTimeThread = null;
        private Thread currentTimeThread = null; private Thread randomNumbersThread = null;
        private Thread randomNumbersThread = null; private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox currentTime;
        private System.Windows.Forms.TextBox currentTime; private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox randomNumbers;
        private System.Windows.Forms.TextBox randomNumbers; private System.Windows.Forms.GroupBox threadManager;
        private System.Windows.Forms.GroupBox threadManager; private System.Windows.Forms.Button pause;
        private System.Windows.Forms.Button pause; private System.Windows.Forms.Button stop;
        private System.Windows.Forms.Button stop; private System.Windows.Forms.Button start;
        private System.Windows.Forms.Button start; private System.Windows.Forms.RadioButton manageTime;
        private System.Windows.Forms.RadioButton manageTime; private System.Windows.Forms.RadioButton manageNumbers;
        private System.Windows.Forms.RadioButton manageNumbers; private System.Windows.Forms.RadioButton manageBoth;
        private System.Windows.Forms.RadioButton manageBoth; private System.ComponentModel.Container components = null;
        private System.ComponentModel.Container components = null;
 public Form1()
        public Form1()
 
         {
{ InitializeComponent();
            InitializeComponent(); 
             //创建新的工作线程
            //创建新的工作线程 currentTimeThread = new Thread(new ThreadStart(CountTime));
            currentTimeThread = new Thread(new ThreadStart(CountTime)); currentTimeThread.IsBackground = true;
            currentTimeThread.IsBackground = true; 
             randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers));
            randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers)); randomNumbersThread.IsBackground = true;
            randomNumbersThread.IsBackground = true; }
        }
 protected override void Dispose( bool disposing )
        protected override void Dispose( bool disposing )
 
         {
{ if( disposing )
            if( disposing )
 
             {
{ if (components != null)
                if (components != null) 
 
                 {
{ components.Dispose();
                    components.Dispose(); }
                } }
            } base.Dispose( disposing );
            base.Dispose( disposing ); }
        }

 UI设计#region UI设计
        UI设计#region UI设计 private void InitializeComponent()
        private void InitializeComponent()
 
         {
{ this.label1 = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label(); this.currentTime = new System.Windows.Forms.TextBox();
            this.currentTime = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label(); this.randomNumbers = new System.Windows.Forms.TextBox();
            this.randomNumbers = new System.Windows.Forms.TextBox(); this.threadManager = new System.Windows.Forms.GroupBox();
            this.threadManager = new System.Windows.Forms.GroupBox(); this.manageBoth = new System.Windows.Forms.RadioButton();
            this.manageBoth = new System.Windows.Forms.RadioButton(); this.manageNumbers = new System.Windows.Forms.RadioButton();
            this.manageNumbers = new System.Windows.Forms.RadioButton(); this.manageTime = new System.Windows.Forms.RadioButton();
            this.manageTime = new System.Windows.Forms.RadioButton(); this.pause = new System.Windows.Forms.Button();
            this.pause = new System.Windows.Forms.Button(); this.stop = new System.Windows.Forms.Button();
            this.stop = new System.Windows.Forms.Button(); this.start = new System.Windows.Forms.Button();
            this.start = new System.Windows.Forms.Button(); this.threadManager.SuspendLayout();
            this.threadManager.SuspendLayout(); this.SuspendLayout();
            this.SuspendLayout(); //
            //  // label1
            // label1 //
            //  this.label1.AutoSize = true;
            this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(8, 24);
            this.label1.Location = new System.Drawing.Point(8, 24); this.label1.Name = "label1";
            this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(79, 13);
            this.label1.Size = new System.Drawing.Size(79, 13); this.label1.TabIndex = 0;
            this.label1.TabIndex = 0; this.label1.Text = "现在的时间:";
            this.label1.Text = "现在的时间:"; //
            //  // currentTime
            // currentTime //
            //  this.currentTime.Location = new System.Drawing.Point(88, 23);
            this.currentTime.Location = new System.Drawing.Point(88, 23); this.currentTime.Name = "currentTime";
            this.currentTime.Name = "currentTime"; this.currentTime.ReadOnly = true;
            this.currentTime.ReadOnly = true; this.currentTime.Size = new System.Drawing.Size(157, 20);
            this.currentTime.Size = new System.Drawing.Size(157, 20); this.currentTime.TabIndex = 1;
            this.currentTime.TabIndex = 1; //
            //  // label2
            // label2 //
            //  this.label2.AutoSize = true;
            this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(14, 56);
            this.label2.Location = new System.Drawing.Point(14, 56); this.label2.Name = "label2";
            this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(43, 13);
            this.label2.Size = new System.Drawing.Size(43, 13); this.label2.TabIndex = 2;
            this.label2.TabIndex = 2; this.label2.Text = "随机数";
            this.label2.Text = "随机数"; //
            //  // randomNumbers
            // randomNumbers //
            //  this.randomNumbers.Location = new System.Drawing.Point(16, 72);
            this.randomNumbers.Location = new System.Drawing.Point(16, 72); this.randomNumbers.Name = "randomNumbers";
            this.randomNumbers.Name = "randomNumbers"; this.randomNumbers.ReadOnly = true;
            this.randomNumbers.ReadOnly = true; this.randomNumbers.Size = new System.Drawing.Size(229, 20);
            this.randomNumbers.Size = new System.Drawing.Size(229, 20); this.randomNumbers.TabIndex = 3;
            this.randomNumbers.TabIndex = 3; //
            //  // threadManager
            // threadManager //
            //  this.threadManager.Controls.Add(this.manageBoth);
            this.threadManager.Controls.Add(this.manageBoth); this.threadManager.Controls.Add(this.manageNumbers);
            this.threadManager.Controls.Add(this.manageNumbers); this.threadManager.Controls.Add(this.manageTime);
            this.threadManager.Controls.Add(this.manageTime); this.threadManager.Controls.Add(this.pause);
            this.threadManager.Controls.Add(this.pause); this.threadManager.Controls.Add(this.stop);
            this.threadManager.Controls.Add(this.stop); this.threadManager.Controls.Add(this.start);
            this.threadManager.Controls.Add(this.start); this.threadManager.Location = new System.Drawing.Point(16, 104);
            this.threadManager.Location = new System.Drawing.Point(16, 104); this.threadManager.Name = "threadManager";
            this.threadManager.Name = "threadManager"; this.threadManager.Size = new System.Drawing.Size(229, 154);
            this.threadManager.Size = new System.Drawing.Size(229, 154); this.threadManager.TabIndex = 7;
            this.threadManager.TabIndex = 7; this.threadManager.TabStop = false;
            this.threadManager.TabStop = false; this.threadManager.Text = "工作线程控制";
            this.threadManager.Text = "工作线程控制"; //
            //  // manageBoth
            // manageBoth //
            //  this.manageBoth.Location = new System.Drawing.Point(34, 74);
            this.manageBoth.Location = new System.Drawing.Point(34, 74); this.manageBoth.Name = "manageBoth";
            this.manageBoth.Name = "manageBoth"; this.manageBoth.Size = new System.Drawing.Size(104, 16);
            this.manageBoth.Size = new System.Drawing.Size(104, 16); this.manageBoth.TabIndex = 12;
            this.manageBoth.TabIndex = 12; this.manageBoth.Text = "同时运行";
            this.manageBoth.Text = "同时运行"; this.manageBoth.CheckedChanged += new System.EventHandler(this.manageBoth_CheckedChanged);
            this.manageBoth.CheckedChanged += new System.EventHandler(this.manageBoth_CheckedChanged); //
            //  // manageNumbers
            // manageNumbers //
            //  this.manageNumbers.Location = new System.Drawing.Point(34, 50);
            this.manageNumbers.Location = new System.Drawing.Point(34, 50); this.manageNumbers.Name = "manageNumbers";
            this.manageNumbers.Name = "manageNumbers"; this.manageNumbers.Size = new System.Drawing.Size(104, 16);
            this.manageNumbers.Size = new System.Drawing.Size(104, 16); this.manageNumbers.TabIndex = 11;
            this.manageNumbers.TabIndex = 11; this.manageNumbers.Text = "更新随机数线程";
            this.manageNumbers.Text = "更新随机数线程"; this.manageNumbers.CheckedChanged += new System.EventHandler(this.manageNumbers_CheckedChanged);
            this.manageNumbers.CheckedChanged += new System.EventHandler(this.manageNumbers_CheckedChanged); //
            //  // manageTime
            // manageTime //
            //  this.manageTime.Location = new System.Drawing.Point(34, 26);
            this.manageTime.Location = new System.Drawing.Point(34, 26); this.manageTime.Name = "manageTime";
            this.manageTime.Name = "manageTime"; this.manageTime.Size = new System.Drawing.Size(104, 16);
            this.manageTime.Size = new System.Drawing.Size(104, 16); this.manageTime.TabIndex = 10;
            this.manageTime.TabIndex = 10; this.manageTime.Text = "更新时间线程";
            this.manageTime.Text = "更新时间线程"; this.manageTime.CheckedChanged += new System.EventHandler(this.manageTime_CheckedChanged);
            this.manageTime.CheckedChanged += new System.EventHandler(this.manageTime_CheckedChanged); //
            //  // pause
            // pause //
            //  this.pause.Location = new System.Drawing.Point(84, 115);
            this.pause.Location = new System.Drawing.Point(84, 115); this.pause.Name = "pause";
            this.pause.Name = "pause"; this.pause.Size = new System.Drawing.Size(54, 23);
            this.pause.Size = new System.Drawing.Size(54, 23); this.pause.TabIndex = 9;
            this.pause.TabIndex = 9; this.pause.Text = "暂停";
            this.pause.Text = "暂停"; this.pause.Click += new System.EventHandler(this.pause_Click);
            this.pause.Click += new System.EventHandler(this.pause_Click); //
            //  // stop
            // stop //
            //  this.stop.Location = new System.Drawing.Point(158, 115);
            this.stop.Location = new System.Drawing.Point(158, 115); this.stop.Name = "stop";
            this.stop.Name = "stop"; this.stop.Size = new System.Drawing.Size(51, 23);
            this.stop.Size = new System.Drawing.Size(51, 23); this.stop.TabIndex = 8;
            this.stop.TabIndex = 8; this.stop.Text = "停止";
            this.stop.Text = "停止"; this.stop.Click += new System.EventHandler(this.stop_Click);
            this.stop.Click += new System.EventHandler(this.stop_Click); //
            //  // start
            // start //
            //  this.start.Location = new System.Drawing.Point(6, 115);
            this.start.Location = new System.Drawing.Point(6, 115); this.start.Name = "start";
            this.start.Name = "start"; this.start.Size = new System.Drawing.Size(50, 23);
            this.start.Size = new System.Drawing.Size(50, 23); this.start.TabIndex = 7;
            this.start.TabIndex = 7; this.start.Text = "开始";
            this.start.Text = "开始"; this.start.Click += new System.EventHandler(this.start_Click);
            this.start.Click += new System.EventHandler(this.start_Click); //
            //  // Form1
            // Form1 //
            //  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(253, 271);
            this.ClientSize = new System.Drawing.Size(253, 271); this.Controls.Add(this.threadManager);
            this.Controls.Add(this.threadManager); this.Controls.Add(this.randomNumbers);
            this.Controls.Add(this.randomNumbers); this.Controls.Add(this.label2);
            this.Controls.Add(this.label2); this.Controls.Add(this.currentTime);
            this.Controls.Add(this.currentTime); this.Controls.Add(this.label1);
            this.Controls.Add(this.label1); this.Name = "Form1";
            this.Name = "Form1"; this.Text = "工作线程和UI的交互";
            this.Text = "工作线程和UI的交互"; this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing); this.threadManager.ResumeLayout(false);
            this.threadManager.ResumeLayout(false); this.ResumeLayout(false);
            this.ResumeLayout(false); this.PerformLayout();
            this.PerformLayout(); }
        } #endregion
        #endregion
 
         [STAThread]
        [STAThread] static void Main()
        static void Main() 
 
         {
{ Application.Run(new Form1());
            Application.Run(new Form1()); }
        }
 private void start_Click(object sender, System.EventArgs e)
        private void start_Click(object sender, System.EventArgs e)
 
         {
{ bool bTime = false, bRandomNumbers = false;
            bool bTime = false, bRandomNumbers = false;
 if( manageTime.Checked || manageBoth.Checked )
            if( manageTime.Checked || manageBoth.Checked ) bTime = true;
                bTime = true; if( manageNumbers.Checked || manageBoth.Checked )
            if( manageNumbers.Checked || manageBoth.Checked ) bRandomNumbers = true;
                bRandomNumbers = true;
 if( bTime )
            if( bTime ) currentTimeThread.Start();
                currentTimeThread.Start(); 
             if( bRandomNumbers )
            if( bRandomNumbers ) randomNumbersThread.Start();
                randomNumbersThread.Start();
 start.Enabled = false;
            start.Enabled = false; stop.Enabled = true;
            stop.Enabled = true; pause.Enabled = true;
            pause.Enabled = true; }
        }
 private void stop_Click(object sender, System.EventArgs e)
        private void stop_Click(object sender, System.EventArgs e)
 
         {
{ bool bTime = false, bRandomNumbers = false;
            bool bTime = false, bRandomNumbers = false;
 if( manageTime.Checked == true || manageBoth.Checked == true )
            if( manageTime.Checked == true || manageBoth.Checked == true ) bTime = true;
                bTime = true; if( manageNumbers.Checked == true || manageBoth.Checked == true )
            if( manageNumbers.Checked == true || manageBoth.Checked == true ) bRandomNumbers = true;
                bRandomNumbers = true;
 if( bTime )
            if( bTime )
 
             {
{ currentTimeThread.Abort();
                currentTimeThread.Abort(); currentTimeThread.Join();
                currentTimeThread.Join();
 currentTimeThread = new Thread(new ThreadStart(CountTime));
                currentTimeThread = new Thread(new ThreadStart(CountTime)); currentTimeThread.IsBackground = true;
                currentTimeThread.IsBackground = true; }
            }
 if( bRandomNumbers )
            if( bRandomNumbers )
 
             {
{ randomNumbersThread.Abort();
                randomNumbersThread.Abort(); randomNumbersThread.Join();
                randomNumbersThread.Join();
 randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers));
                randomNumbersThread = new Thread(new ThreadStart(GenerateRandomNumbers)); randomNumbersThread.IsBackground = true;
                randomNumbersThread.IsBackground = true; }
            }
 start.Enabled = true;
            start.Enabled = true; stop.Enabled = false;
            stop.Enabled = false; pause.Enabled = false;
            pause.Enabled = false; }
        }
 private void pause_Click(object sender, System.EventArgs e)
        private void pause_Click(object sender, System.EventArgs e)
 
         {
{ bool bTime = false, bRandomNumbers = false;
            bool bTime = false, bRandomNumbers = false;
 if( manageTime.Checked == true || manageBoth.Checked == true )
            if( manageTime.Checked == true || manageBoth.Checked == true ) bTime = true;
                bTime = true; if( manageNumbers.Checked == true || manageBoth.Checked == true )
            if( manageNumbers.Checked == true || manageBoth.Checked == true ) bRandomNumbers = true;
                bRandomNumbers = true;
 if( bTime )
            if( bTime )
 
             {
{ if( 0 != (currentTimeThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) )
                if( 0 != (currentTimeThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) ) currentTimeThread.Resume();
                    currentTimeThread.Resume(); else
                else currentTimeThread.Suspend();
                    currentTimeThread.Suspend(); }
            }

 if( bRandomNumbers )
            if( bRandomNumbers )
 
             {
{ if( 0 != (randomNumbersThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) )
                if( 0 != (randomNumbersThread.ThreadState & ( ThreadState.Suspended | ThreadState.SuspendRequested ) ) ) randomNumbersThread.Resume();
                    randomNumbersThread.Resume(); else
                else randomNumbersThread.Suspend();
                    randomNumbersThread.Suspend(); }
            } }
        }
 private void manageTime_CheckedChanged(object sender, System.EventArgs e)
        private void manageTime_CheckedChanged(object sender, System.EventArgs e)
 
         {
{ }
        }
 private void manageNumbers_CheckedChanged(object sender, System.EventArgs e)
        private void manageNumbers_CheckedChanged(object sender, System.EventArgs e)
 
         {
{ }
        }
 private void manageBoth_CheckedChanged(object sender, System.EventArgs e)
        private void manageBoth_CheckedChanged(object sender, System.EventArgs e)
 
         {
{ }
        }

 /**//// <summary>
        /**//// <summary> /// 注意其Invoke的使用,其有两种使用形式
        /// 注意其Invoke的使用,其有两种使用形式 /// public void Invoke(System.Delegate delegate);
        /// public void Invoke(System.Delegate delegate); /// public void Invoke(System.Delegate delegate, object [] args);
        /// public void Invoke(System.Delegate delegate, object [] args); /// </summary>
        /// </summary> public void CountTime()
        public void CountTime()
 
         {
{ while(true)
            while(true)
 
             {
{ Invoke(new UpdateTimeDelegate(updateCurrentTime));
                Invoke(new UpdateTimeDelegate(updateCurrentTime)); Thread.Sleep(1000);
                Thread.Sleep(1000); }
            } }
        }
 public void GenerateRandomNumbers()
        public void GenerateRandomNumbers()
 
         {
{ int [] randomNumbers = new int[10];
            int [] randomNumbers = new int[10]; Random r = new Random();
            Random r = new Random();
 while(true)
            while(true)
 
             {
{ for(int i = 0; i < randomNumbers.Length; i++)
                for(int i = 0; i < randomNumbers.Length; i++) randomNumbers[i] = r.Next(1, 100);
                    randomNumbers[i] = r.Next(1, 100);

 Invoke(new UpdateRandomNumbers(updateRandomNumbers), new object[]
                Invoke(new UpdateRandomNumbers(updateRandomNumbers), new object[]  { randomNumbers });
{ randomNumbers }); Thread.Sleep(500);
                Thread.Sleep(500); }
            } }
        }

 /**//// <summary>
        /**//// <summary> /// 负责更新UI界面中时间显示的函数
        /// 负责更新UI界面中时间显示的函数 /// </summary>
        /// </summary> private void updateCurrentTime()
        private void updateCurrentTime()
 
         {
{ currentTime.Text = DateTime.Now.ToLongTimeString();
            currentTime.Text = DateTime.Now.ToLongTimeString(); }
        }
 
        
 /**//// <summary>
        /**//// <summary> /// 负责更新UI界面中随机数显示的函数
        /// 负责更新UI界面中随机数显示的函数 /// </summary>
        /// </summary> /// <param name="numbers"></param>
        /// <param name="numbers"></param> private void updateRandomNumbers(int [] numbers)
        private void updateRandomNumbers(int [] numbers)
 
         {
{ System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
 foreach(int i in numbers)
            foreach(int i in numbers) sb.Append(i.ToString()).Append(", ");
                sb.Append(i.ToString()).Append(", ");
 randomNumbers.Text = sb.ToString();
            randomNumbers.Text = sb.ToString(); }
        }
 private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
 
         {
{ if( (randomNumbersThread.ThreadState & ThreadState.Running) == ThreadState.Running )
            if( (randomNumbersThread.ThreadState & ThreadState.Running) == ThreadState.Running ) randomNumbersThread.Abort();
                randomNumbersThread.Abort();
 randomNumbersThread = null;
            randomNumbersThread = null; 
             if( (currentTimeThread.ThreadState & ThreadState.Running) == ThreadState.Running )
            if( (currentTimeThread.ThreadState & ThreadState.Running) == ThreadState.Running ) currentTimeThread.Abort();
                currentTimeThread.Abort();
 currentTimeThread = null;
            currentTimeThread = null; }
        } }
    }
 public delegate void UpdateTimeDelegate();
    public delegate void UpdateTimeDelegate(); public delegate void UpdateRandomNumbers(int [] numbers);
    public delegate void UpdateRandomNumbers(int [] numbers); }
}
其实在C# 2.0 中所有的Control类都有Invoke()方法,如果负责更新UI元素的函数不是定义在Main()中,那么必须首先检测Control类中的InvokeRequired属性。举个例子吧,注意setProgressBarValue()函数中调用自己的方式.
//在工作线程中更新主窗口进度条
public void setProgressBarValue(ProgressBar progressBar1,int value)
{
if (progressBar1.InvokeRequired)
{
object[] parameters = new object[] { value };
progressBar1.Invoke(new setProgressBarValueDelegate(setProgressBarValue), parameters);
}
else
progressBar1.Value = value;
}
这里的一些代码参考了http://www.codeproject.com 的例子.
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号