2

我正在使用 BackgroundWorker 线程来执行一个长任务(基本上是读取一个大的 xml 文件)。工作人员第一次按要求正常工作,但如果我上传第二个 xml 文件,使用相同的后台工作人员有时工作正常,但大多数情况下,后台工作人员的 RunWorkerCompleted 甚至在 DoWork 事件之前被触发。部分代码如下所示

    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 是一个全局定义的变量。我不明白这里有什么问题。请帮助

4

4 回答 4

9

您应该在调用之前DoWork添加-event 处理程序(以及所有其他事件处理程序)。RunWorkerAsync()

否则,可能会发生RunWorkerAsync实际上什么都不做的情况。

于 2013-07-29T13:38:54.890 回答
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应该在订阅DoWorkandRunWokerCompleted事件后调用。

于 2013-07-29T13:47:42.690 回答
2

你应该首先检查后台工作人员是否忙,使用这个....

        backgroundWorker1.DoWork += backgroundWorker1_DoWork;
        backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
        if (backgroundWorker1.IsBusy)
        {
            backgroundWorker1.CancelAsync();
        }
        else
        {
            backgroundWorker1.RunWorkerAsync();

        }
于 2014-02-20T05:13:07.007 回答
0

正如https://stackoverflow.com/a/16809596/8029935中所说,当 DoWork 方法因异常而死时,您可以盲目地假设工作人员已经完成了工作并产生了结果。它被 BackgroundWorker 捕获并作为 e.Error 属性传递给 RunWorkerCompleted 事件处理程序。

因此,我建议您必须使用 try/catch 语句检查该属性。

于 2019-04-25T03:14:27.573 回答