我使用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是全局定义的变量。这里有什么问题我没有得到。请帮助
答案 0 :(得分:9)
您应该在调用DoWork
之前添加RunWorkerAsync()
- 事件处理程序(以及所有其他事件处理程序)。
否则,RunWorkerAsync
几乎什么都不会发生。
答案 1 :(得分:2)
应该是这样的:
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
事件后,应调用{p> RunWokerCompleted
。
答案 2 :(得分:2)
你应首先检查后台工作人员是否忙碌,使用此....
backgroundWorker1.DoWork += backgroundWorker1_DoWork; backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
if (backgroundWorker1.IsBusy)
{
backgroundWorker1.CancelAsync();
}
else
{
backgroundWorker1.RunWorkerAsync();
}
答案 3 :(得分:0)
如https://stackoverflow.com/a/16809596/8029935中所述,您可以盲目地假定当DoWork方法因异常死亡时,工作人员已完成工作并产生了结果。它被BackgroundWorker捕获,并作为e.Error属性传递给RunWorkerCompleted事件处理程序。
因此,我建议您必须使用try / catch语句检查该属性。