学习C#中多线程方法(一):
WinFrom应用中,创建一个单独的线程执行执行一定的操作,为了向用户现实程序进度,在form中添加progressBar 控件现实进度,通过label显示提示字串。
1. 创建Form,添加progressBar,label, Button 控件
2. 添加引用 system.threading. 这个引用用来创建线程启动操作。
最初的程序为:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Threading; namespace ProgressBarTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(RunOnTimerThread)); thread.IsBackground = true; thread.Start(); } private void RunOnTimerThread() { if (progressBar1.Value != 100) { progressBar1.Value += 1; //抛出异常 } if (progressBar2.Value != 100) progressBar2.Value += 10; //抛出异常 Thread.Sleep(1000); label1.Text = System.DateTime.Now.ToString(); //抛出异常 } } }
在编译过程中会返回以下exception: Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on.
这里涉及到多线程控制的安全问题,在windows的编程中有这样一个原则,在窗体创建线程之外的任何线程中都不能操作窗体。要解决这个问题,可以调用控件提供的Invoke和BeginInvoke把调用“封送回”窗体创建线程,让程序在窗体创建线程上修改控件属性。下面是修改后的程序:
private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(new ThreadStart(StartSomeWorkFromUIThread)); thread.IsBackground = true; thread.Start(); } private void StartSomeWorkFromUIThread() { if (this.InvokeRequired) BeginInvoke(new EventHandler(RunOnTimerThread), null); else RunOnTimerThread(this, null); } private void RunOnTimerThread(object sender, EventArgs e) { if (progressBar1.Value != 100) { progressBar1.Value += 1; } if (progressBar2.Value != 100) progressBar2.Value += 10; Thread.Sleep(1000); label1.Text = System.DateTime.Now.ToString(); }
参考: http://www.cnblogs.com/jianglai11/articles/1708330.htmlhttp://www.cnblogs.com/net66/archive/2005/08/03/206132.html