在什么情况下后台工作者不会运行DoWork方法来完成?

发布于 2024-08-12 15:31:08 字数 664 浏览 8 评论 0原文

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

当我单击表单上的按钮时,将运行以下内容:

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 Exception,但我在 DoWork 方法的末尾实例化了该对象。

我知道 DoWork 没有运行,因为如果我在使用它之前进行空检查,再次按下表单上的按钮...它就会运行,并且一切都按预期工作。

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

I've got a background worker on a form and I've written some long running DB interaction in it.

When I click a button on my form, the following runs:

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

Where bwFind is the BackgroundWorker and param is a DevExpress CriteriaOperator.

I update a progressbar in the Progress_Changed event handler.

And I do the following in the RunWorkerCompleted event handler:

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

Problem is, that I get a Null Ref Exception at the line noted, however I instantiate that object, at the end of the DoWork method.

I know that DoWork isn't running, cause if I do a null-check before using it, press the button on the form a second time... it runs, and all works as expected.

Maybe I'm not using the BackgroundWorker correctly, but this happens very often whenever I use the component.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

被翻牌 2024-08-19 15:31:08

实现 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
    }

There is a specific pattern for implementing RunWorkerCompleted.

  • First, Check e.Error (Exceptions)
  • Second, Check for Cancelation, if supported
  • And finally, Accept result

And you normally assign the result to e.Result in DoWork to transfer it to RunWorkerCompleted, but you use a class member for that. Make sure the use of this.dataObject is thread-safe.

   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
    }
怪我入戏太深 2024-08-19 15:31:08

还有一个问题。如果父线程被终止/中止,您将无法Complete

There is one more issue. You'll not get you Complete if the parent thread was killed/aborted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文