我使用BackgroundWorker线程执行一个长任务(基本上读取一个大的xml文件)。工作人员第一次按照需要正常工作,但如果我上传第二个xml文件,使用相同的后台工作程序,它有时可以正常工作,但大多数情况下,即使在DoWork事件之前,BackgroundWorker的RunWorkerCompleted也会被触发。部分代码显示如下
private void openFile_Click(object sender, RoutedEventArgs e)
{
// Code removed for brevity
worker = new BackgroundWorker();
worker.RunWorkerAsync();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.WorkerReportsProgress = true;
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
DataImport();
//worker.Dispose();
//worker.Disposed += new EventHandler(worker_Disposed);
//worker.DoWork -= worker_DoWork;
//worker.RunWorkerCompleted -= worker_RunWorkerCompleted;
//worker = null;
//GC.Collect(GC.GetGeneration(worker), GCCollectionMode.Forced);
}
worker是全局定义的变量。这里有什么问题我没有得到。请帮助
在调用DoWork
之前,您应该添加RunWorkerAsync()
事件处理程序(以及所有其他事件处理程序)。
否则,可能会发生RunWorkerAsync
几乎什么也没做。
它应该是这样的:
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged +=
new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
在订阅RunWorkerAsync
和DoWork
事件后应该召集RunWokerCompleted
。
你应该首先检查后台工作人员是否忙碌,使用这....
backgroundWorker1.DoWork += backgroundWorker1_DoWork; backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
if (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
}
else
{
backgroundWorker1.RunWorkerAsync();
}
正如在https://stackoverflow.com/a/16809596/8029935中所说的那样,你可以盲目地假设工人已完成工作并在DoWork方法因异常而死亡时产生结果。它由BackgroundWorker捕获并作为e.Error属性传递给RunWorkerCompleted事件处理程序。
所以,我建议您必须使用try / catch语句检查该属性。