在WinForm中经常遇到一些费时的操作界面,比如统计某个磁盘分区的文件夹或者文件数目,如果分区很大或者文件过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,为了解决这个问题,可以使用委托来处理,在.net2.0中还可以用BackgroundWorker类。
BackgroundWorker类是.net 2.0里新增加的一个类,对于需要长时间操作而不需要用户长时间等待的情况可以使用这个类。
注意确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。
程序代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Text;
usingSystem.Windows.Forms;
/*
*作者:周公
*BackgroundWorker类是.net2.0里新增加的一个类,对于需要长时间操作而不需要用户长时间等待的情况可以使用这个类。
*注意确保在DoWork事件处理程序中不操作任何用户界面对象。而应该通过ProgressChanged和RunWorkerCompleted事件与用户界面进行通信。
*它有几个属性:
*CancellationPending——指示应用程序是否已请求取消后台操作。
*IsBusy——指示BackgroundWorker是否正在运行异步操作
*WorkerReportsProgress——该值指示BackgroundWorker能否报告进度更新
*WorkerSupportsCancellation——该值指示BackgroundWorker是否支持异步取消
*还有如下事件:
*DoWork——调用RunWorkerAsync时发生。
*ProgressChanged——调用ReportProgress时发生。
*RunWorkerCompleted——当后台操作已完成、被取消或引发异常时发生。
*
*还有如下方法:
*CancelAsync——请求取消挂起的后台操作
*ReportProgress——引发ProgressChanged事件
*RunWorkerAsync——开始执行后台操作
*
**/
namespaceBackgroundWorkerDemo
{
publicpartialclassMainForm:Form
{
privateBackgroundWorkerworker=newBackgroundWorker();
publicMainForm()
{
InitializeComponent();
worker.WorkerReportsProgress=true;
worker.WorkerSupportsCancellation=true;
//正式做事情的地方
worker.DoWork+=newDoWorkEventHandler(DoWork);
//任务完称时要做的,比如提示等等
worker.ProgressChanged+=newProgressChangedEventHandler(ProgessChanged);
//任务进行时,报告进度
worker.RunWorkerCompleted+=newRunWorkerCompletedEventHandler(CompleteWork);
}
//调用RunWorkerAsync时发生
publicvoidDoWork(objectsender,DoWorkEventArgse)
{
e.Result=ComputeFibonacci(worker,e);//当ComputeFibonacci(worker,e)返回时,异步过程结束
}
//调用ReportProgress时发生
publicvoidProgessChanged(objectsender,ProgressChangedEventArgse)
{
this.progressBar1.Value=e.ProgressPercentage;
}
//当后台操作已完成、被取消或引发异常时发生
publicvoidCompleteWork(objectsender,RunWorkerCompletedEventArgse)
{
MessageBox.Show("完成!");
}
privateintComputeFibonacci(objectsender,DoWorkEventArgse)
{
for(inti=0;i<1000;i++)
{
if(worker.CancellationPending)
{
e.Cancel=true;
return -1;
}
else
{
}
System.Threading.Thread.Sleep(10);
}
return-1;
}
privatevoidbtnStart_Click(objectsender,EventArgse)
{
worker.RunWorkerAsync();
btnStart.Enabled=false;
btnPause.Enabled=true;
}
privatevoidbtnPause_Click(objectsender,EventArgse)
{
btnPause.Enabled=false;
btnStart.Enabled=true;
worker.CancelAsync();
}
}
}
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Text;
usingSystem.Windows.Forms;
/*
*作者:周公
*BackgroundWorker类是.net2.0里新增加的一个类,对于需要长时间操作而不需要用户长时间等待的情况可以使用这个类。
*注意确保在DoWork事件处理程序中不操作任何用户界面对象。而应该通过ProgressChanged和RunWorkerCompleted事件与用户界面进行通信。
*它有几个属性:
*CancellationPending——指示应用程序是否已请求取消后台操作。
*IsBusy——指示BackgroundWorker是否正在运行异步操作
*WorkerReportsProgress——该值指示BackgroundWorker能否报告进度更新
*WorkerSupportsCancellation——该值指示BackgroundWorker是否支持异步取消
*还有如下事件:
*DoWork——调用RunWorkerAsync时发生。
*ProgressChanged——调用ReportProgress时发生。
*RunWorkerCompleted——当后台操作已完成、被取消或引发异常时发生。
*
*还有如下方法:
*CancelAsync——请求取消挂起的后台操作
*ReportProgress——引发ProgressChanged事件
*RunWorkerAsync——开始执行后台操作
*
**/
namespaceBackgroundWorkerDemo
{
publicpartialclassMainForm:Form
{
privateBackgroundWorkerworker=newBackgroundWorker();
publicMainForm()
{
InitializeComponent();
worker.WorkerReportsProgress=true;
worker.WorkerSupportsCancellation=true;
//正式做事情的地方
worker.DoWork+=newDoWorkEventHandler(DoWork);
//任务完称时要做的,比如提示等等
worker.ProgressChanged+=newProgressChangedEventHandler(ProgessChanged);
//任务进行时,报告进度
worker.RunWorkerCompleted+=newRunWorkerCompletedEventHandler(CompleteWork);
}
//调用RunWorkerAsync时发生
publicvoidDoWork(objectsender,DoWorkEventArgse)
{
e.Result=ComputeFibonacci(worker,e);//当ComputeFibonacci(worker,e)返回时,异步过程结束
}
//调用ReportProgress时发生
publicvoidProgessChanged(objectsender,ProgressChangedEventArgse)
{
this.progressBar1.Value=e.ProgressPercentage;
}
//当后台操作已完成、被取消或引发异常时发生
publicvoidCompleteWork(objectsender,RunWorkerCompletedEventArgse)
{
MessageBox.Show("完成!");
}
privateintComputeFibonacci(objectsender,DoWorkEventArgse)
{
for(inti=0;i<1000;i++)
{
if(worker.CancellationPending)
{
e.Cancel=true;
return -1;
}
else
{
}
System.Threading.Thread.Sleep(10);
}
return-1;
}
privatevoidbtnStart_Click(objectsender,EventArgse)
{
worker.RunWorkerAsync();
btnStart.Enabled=false;
btnPause.Enabled=true;
}
privatevoidbtnPause_Click(objectsender,EventArgse)
{
btnPause.Enabled=false;
btnStart.Enabled=true;
worker.CancelAsync();
}
}
}
intpercent=100*i/1000;//计算已完成的百分比
worker.ReportProgress(percent);