Question

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.

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

Form1 looks like this...

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...

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

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.

Was it helpful?

Solution

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

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

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

OTHER TIPS

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

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.

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

I could be wrong but that should give some pointers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top