查询数据量很大或者过多的话,处理不好就会造成“假死”的情况,或者报“线程间操作无效”的异常,为了解决这个问题,可以使用委托来处理,在.net2.0中还可以用BackgroundWorker类。
BackgroundWorker类是.net 2.0里新增加的一个类,对于需要长时间操作而不需要用户长时间等待的情况可以使用这个类。
MakeSure:在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信
/*
* BackgroundWorker类是.net 2.0里新增加的一个类,对于需要长时间操作而不需要用户长时间等待的情况可以使用这个类。
* 注意确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。
* 它有几个属性:
* CancellationPending——指示应用程序是否已请求取消后台操作。
* IsBusy——指示 BackgroundWorker 是否正在运行异步操作
* WorkerReportsProgress——该值指示 BackgroundWorker 能否报告进度更新
* WorkerSupportsCancellation——该值指示 BackgroundWorker 是否支持异步取消
* 还有如下事件:
* DoWork——调用 RunWorkerAsync 时发生。
* ProgressChanged——调用 ReportProgress 时发生。
* RunWorkerCompleted——当后台操作已完成、被取消或引发异常时发生。
*
* 还有如下方法:
* CancelAsync——请求取消挂起的后台操作
* ReportProgress——引发 ProgressChanged 事件
* RunWorkerAsync——开始执行后台操作
*
**/
_backDetail.WorkerReportsProgress = true;//该值指示 BackgroundWorker 能否报告进度更新
_backDetail.WorkerSupportsCancellation = true;//该值指示 BackgroundWorker 是否支持异步取消
_backDetail.DoWork += _backDetail_DoWork;//调用 RunWorkerAsync 时发生
_backDetail.ProgressChanged += _backDetail_ProgressChanged;//调用 ReportProgress 时发生
_backDetail.RunWorkerCompleted += _backDetail_RunWorkerCompleted; //当后台操作已完成、被取消或引发异常时发生
//调用 ReportProgress 时发生
void _backDetail_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
//当后台操作已完成、被取消或引发异常时发生
void _backDetail_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
_comCollectReport.SetReoprt();
SetWriterPeople();
btnReport.Enabled = true;
progressPanel1.Visible = false;
progressBar1.Value = 0;
progressBar1.Visible = false;
}
//调用 RunWorkerAsync 时发生
void _backDetail_DoWork(object sender, DoWorkEventArgs e)
{
GetResult();
GetServiceSoapClient();
GetServiceDataDetialByProc();
ComputeFibonacci(_backDetail,e);
}
public int ComputeFibonacci(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 1000; i++)
{
if (_backDetail.CancellationPending)
{
e.Cancel = true;
}
else
{
_backDetail.ReportProgress(i);
}
System.Threading.Thread.Sleep(10);
}
return -1;
}