对于没有触发的BackgroundWorker事件感到困惑

时间:2022-08-24 21:02:11

This may seem like a somewhat contrived example, but I'm left scratching my head.

这可能看起来像是一个有点人为的例子,但我只是摸不着头脑。

Ok, I have a console app that instantiates a WindowsForm and calls a method called DoSomeWork() on the form.

好吧,我有一个控制台应用程序,它实例化一个WindowsForm并在窗体上调用一个名为DoSomeWork()的方法。

class Program
  { 
    static void Main(string[] args)
    {
      Form1 form = new Form1();         
      form.DoSomeWork();   
    }
  }

Form1 looks like this...

Form1看起来像这样......

public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    public void DoSomeWork()
    {
      OuterClass outerClass = new OuterClass();
      outerClass.DoSomeWork();
    }    
  }

Outer class, in turn, looks like this...

反过来,外类看起来像......

public class OuterClass
  {
    public void DoSomeWork()
    {
      InnerClass innerClass = new InnerClass();
      innerClass.DoSomeWork();
    }
  }

And finally InnerClass looks like this...

最后,InnerClass看起来像这样......

public class InnerClass
  {
    private BackgroundWorker _backgroundWorker = new BackgroundWorker();

    public InnerClass()
    {
      _backgroundWorker.WorkerReportsProgress = true;
      _backgroundWorker.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);
      _backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
    }

    void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
      int i = 0; //I've placed a break point here. But it's never hit
    }

    void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
      BackgroundWorker worker = sender as BackgroundWorker;

      worker.ReportProgress(42);
    }

    public void DoSomeWork()
    {
      _backgroundWorker.RunWorkerAsync();
    }
  }

For a reason unknown (to me), the BacgroundWorker in InnerClass never seems to fire the ProgressChanged event. If I replace

由于一个未知的原因(对我而言),InnerClass中的BacgroundWorker似乎永远不会触发ProgressChanged事件。如果我更换

Form1 form = new Form1();

with

OuterClass outerClass = new OuterClass()

in class Program, it works fine. So why is that my events don't fire when I'm calling the same methods through a Form?

在课程计划中,它工作正常。那么,当我通过表单调用相同的方法时,为什么我的事件不会触发?

Thanks!

EDIT: I seemed to be throwing people off by leaving the ProgressChanged event handler as throwing a NotImplementedException, so I've removed it for clarity.

编辑:我似乎是通过将ProgressChanged事件处理程序保留为抛出NotImplementedException来抛弃人员,所以我为了清楚起见删除了它。

2 个解决方案

#1


6  

You forgot to start a message loop, calling Application.Run() is required. Without a message loop, the BackgroundWorker events cannot work. To fix:

您忘记启动消息循环,需要调用Application.Run()。如果没有消息循环,BackgroundWorker事件将无法工作。修理:

static void Main(string[] args)
{
  Application.Run(new Form1());   
}

Call DoSomeWork() in the form's constructor or it's Load event.

在窗体的构造函数中调用DoSomeWork()或它的Load事件。

#2


2  

Did you actually throw NotImplementedException(); in the handler? or you're just mocking this up quick and forgot to remove it?

你真的抛出NotImplementedException();在处理程序?或者你只是快速嘲笑这个并忘记删除它?

My guess would be that it is related to different thread apartment models being utilized.

我的猜测是它与使用的不同线程公寓模型有关。

From my experience if a single-thread-apartment non-UI thread throws an exception outside of the main UI thread, that thread will simply dies without any warning.

根据我的经验,如果单线程公寓非UI线程在主UI线程之外抛出异常,那么该线程将在没有任何警告的情况下死掉。

Windows Forms require a different apartment model than Console applications if I remember correctly. That could be the source of the problem.

如果我没记错的话,Windows窗体需要与控制台应用程序不同的公寓模型。这可能是问题的根源。

I could be wrong but that should give some pointers.

我可能错了,但应该给出一些指示。

#1


6  

You forgot to start a message loop, calling Application.Run() is required. Without a message loop, the BackgroundWorker events cannot work. To fix:

您忘记启动消息循环,需要调用Application.Run()。如果没有消息循环,BackgroundWorker事件将无法工作。修理:

static void Main(string[] args)
{
  Application.Run(new Form1());   
}

Call DoSomeWork() in the form's constructor or it's Load event.

在窗体的构造函数中调用DoSomeWork()或它的Load事件。

#2


2  

Did you actually throw NotImplementedException(); in the handler? or you're just mocking this up quick and forgot to remove it?

你真的抛出NotImplementedException();在处理程序?或者你只是快速嘲笑这个并忘记删除它?

My guess would be that it is related to different thread apartment models being utilized.

我的猜测是它与使用的不同线程公寓模型有关。

From my experience if a single-thread-apartment non-UI thread throws an exception outside of the main UI thread, that thread will simply dies without any warning.

根据我的经验,如果单线程公寓非UI线程在主UI线程之外抛出异常,那么该线程将在没有任何警告的情况下死掉。

Windows Forms require a different apartment model than Console applications if I remember correctly. That could be the source of the problem.

如果我没记错的话,Windows窗体需要与控制台应用程序不同的公寓模型。这可能是问题的根源。

I could be wrong but that should give some pointers.

我可能错了,但应该给出一些指示。