在开发的过程中,我们肯定会用到多线程。创建多线程的方法很简单,但是在WINFORM的开发中,你会发现新创的线程是不允许访问界面上的控件的,真是一件非常令人头疼的事情。网上有很多解决方法,方便的不安全,安全的使用起来都非常麻烦。前不久看见一个控件backgroundWorker,可以很好的解决这个问题。
首先从VS编辑器组件一栏拖一个backgroundWorker到FROM上。
你会发现这个控件的属性很少,最重要的有2个:
WorkrReportsProgress 线程是否报告进度
意思是这个线程每执行一步操作,都可以传一些数据到线程外面,用来报告它的进度。如果你设置为FALSE,它就不会报告进度了。一般当然要设成TRUE啦!至于为什么默认是FALSE,我想设会TRUE应该会有一些性能上的限制吧!但是用于普通的开发已经足够足够了,尽管设为TRUE,别怕。
WorkerSupportsCancel 线程是否支持取消
就是说线程执行到一半的时候,能不能被强制中断。这个要看你实际应用了。如果你觉得任何可能引发线程中断的操作,都不会引发程序崩溃,那么就设成TRUE好了,方便也方便点。
好,现在介绍它的3个重要方法。
DoWork()把你要执行的代码写在DoWork()里,线程启动后,就是去执行DoWork()里面的代码。
ProgressChanged()用于接收线程内部传出来的数据。可在这个方法中直接操作用户界面。
RunWorkCompleted()线程执行完毕后,将执行这个方法。
好,现在开始实际操作:
首先将WorkrReportsProgress设置为TRUE,在属性面板里就可以设置了。
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
>>>在数据库中查询数据的操作,代码略,总之得到一个datatable临时表<<<
//使用ReportProgress向外面传送数据。可传送一个int数值,一个OBJECT。
backgroundWorker1.ReportProgress(0,datatable)
//一般int那个是用来传递当前循环次数的,用于外面的进度条,对现在来说没有意义,写个0就可以。OBJECT么直接把datatable传递出去就可以了。
}
private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
//e的ProgressPercentage属性就是刚才传出来的int
int i=e.ProgressPercentage;
//e的UserState属性这就是刚才传出来的datatable了,要强制转换一下才能用的
datatable=e.UserState
>>>然后在界面上处理datatable的信息就可以了<<<
}
//点击按钮,启动线程!注意做一下线程是否忙碌的判断
private void btnSearch_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
//启动线程
backgroundWorker1.RunWorkerAsync();
}
}
代码就是这样,至于总之原理很简单。在多线程中做动作,把动作的结果,需要反馈到用户界面上的元素,用过ReportProgress传出来,用ProgressChanged接收。就可以了。
其他的,就留给你举一反三把!