【问题标题】:Under what circumstances will a backgroundworker not run the DoWork method to completion?什么情况下后台工作者不会运行 DoWork 方法完成?
【发布时间】:2009-11-25 19:52:14
【问题描述】:

我在表单上有一个后台工作人员,我在其中编写了一些长期运行的数据库交互。

当我单击表单上的按钮时,会运行以下命令:

if (!bwFind.IsBusy)
    bwFind.RunWorkerAsync(param);

其中 bwFind 是 BackgroundWorker,param 是 DevExpress CriteriaOperator。

我在 Progress_Changed 事件处理程序中更新了一个进度条。

我在 RunWorkerCompleted 事件处理程序中执行以下操作:

dataGrid.DataSource = this.dataObject;
dataGrid.Refresh();
label1.Text = this.dataObject.Count.ToString(); // problem appears here

问题是,我在指出的行中得到了 Null Ref 异常,但是我在 DoWork 方法的末尾实例化了该对象。

我知道 DoWork 没有运行,因为如果我在使用它之前进行空值检查,请再次按下表单上的按钮...它会运行,并且一切正常。

也许我没有正确使用 BackgroundWorker,但每当我使用该组件时,这种情况经常发生。

【问题讨论】:

  • 这很明显我敢肯定,但是当异常被抛出时你已经检查了 this.dataObject 的值对吗?
  • 它肯定是空的,但关键是它不应该是空的。它是在 DoWork 中设置的(由于跨线程操作而退出)

标签: c# .net backgroundworker


【解决方案1】:

implementing RunWorkerCompleted 有一个特定的模式。

  • 首先,检查 e.Error(例外)
  • 其次,检查是否取消(如果支持)
  • 最后,接受结果

您通常将结果分配给 DoWork 中的 e.Result 以将其传输给 RunWorkerCompleted,但您为此使用了一个类成员。确保this.dataObject 的使用是线程安全的。

   void backgroundWorker1_RunWorkerCompleted(object sender, 
        RunWorkerCompletedEventArgs e)
    {
        // First, handle the case where an exception was thrown.
        if (e.Error != null)
        {
            label1.Text = e.Error.Message;
        }
        else if (e.Cancelled)
        {
            label1.Text = "Canceled";
        }
        else
        {
            // Finally, handle the case where the operation 
            // succeeded.
            label1.Text = this.dataObject.Count.ToString();
        }

        // update UI for Thread completed
    }

【讨论】:

  • 原来我正在修改 DoWork 中的 UI 项。检查 e.Error.Message 表明了这一点。谢谢你。我认为使用 BackgroundWorker 的全部意义在于我不必(开始)调用?
  • 你仍然需要从 DoWork 调用。 (仅)将 Completed 和 Progress 事件调用到主线程。
【解决方案2】:

还有一个问题。如果父线程被杀死/中止,您将不会得到Complete

【讨论】:

  • 他在父线程(==主线程)中得到了空引用异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-13
  • 2013-04-28
  • 1970-01-01
  • 2021-09-05
  • 2018-08-25
  • 1970-01-01
  • 2019-04-29
相关资源
最近更新 更多