Onsightfree
Onsightfree

Reputation: 357

Explain to me this BackgroundWorker Event please

I am experimenting with BackgroundWorker, and trying to notify my main Thread per an Event. These things are all new to me, and wanted to ask, if I am doing it OK.

I simplified a winforms problem of mine, in the following way: (It has only 1 Button, and counts to ten in another Thread when I press it)

public partial class Form1 : Form
{
    public void Subscribe(CountToTen c)
    {
        c.HandleWorkerEvent += new CountToTen.WorkerHandler(OtherThreadFinished);
    }
    private void OtherThreadFinished(CountToTen c, EventArgs e)
    {
        Debug.WriteLine("I'm ready !!!");
    }

    public Form1()
    {
        InitializeComponent();
    }

    private void btn_do_Click(object sender, EventArgs e)
    {
        CountToTen newThread = new CountToTen();
        Subscribe(newThread);
        newThread.StartCountingAndReportIfFinished();
    }
}

CountToTen class:

public class CountToTen
{

    public event WorkerHandler HandleWorkerEvent;
    public EventArgs e;
    public delegate void WorkerHandler(CountToTen c, EventArgs e);
    public void StartCountingAndReportIfFinished()
    {
        BackgroundWorker worker = new BackgroundWorker();

        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            for (int i = 1; i <= 10; i++)
            {
                Thread.Sleep(300);
                Debug.WriteLine("Counting :" + i.ToString());

            }
        };

        worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs args)
            {
                Debug.WriteLine("Fromt Thread2 : I am finished!");
                if (HandleWorkerEvent != null)
                {
                    HandleWorkerEvent(this, e);
                }
            });

        worker.RunWorkerAsync();
        worker.Dispose();
    }
}

I was trying to create an event, when the BW is finished, and subscribe to this event in my main form. It works fine, but, I do not really understand what happens in this line:

worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object o, RunWorkerCompletedEventArgs args)
            {
                Debug.WriteLine("Fromt Thread2 : I am finished!");
                if (HandleWorkerEvent != null)
                {
                    HandleWorkerEvent(this, e);
                }
            });

Am I not creating an event here for my BW, when it is finished, and then call the another for the main thread? Is it not overkill? Could I subscribe directly to the RunWorkerCompleteEventHandler as well?

I'm a bit confused here, please enlighten a beginner. Thanks

Upvotes: 3

Views: 519

Answers (3)

C-va
C-va

Reputation: 2910

Am I not creating an event here for my BW, when it is finished,
 and then call the another for the main thread?

Yes.. You are handling the events of BackgroundWorker in your CountToTen class. And Obviously as per your class architecture the only way to notify your mainform through Event.

  Is it not overkill? Could I subscribe directly to the RunWorkerCompleteEventHandler
  as well? 

Ofcourse you can..Your BackgroundWorker is not exposed directly to the mainform else you can subscribe the RunWorkerCompletedEvent from there itself.

Note: You don't have to call Dispose(). It implements the IDisposable interface via Component. For detail see here

Update

  • Alternative way

    public partial class Form1 : Form
    {
      private void btn_do_Click(object sender, EventArgs e)
      { 
        CountToTen obj= new CountToTen();
         obj.bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
         obj.bw.RunWorkerAsync();
       }
    
       void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){}       
    }
    class CountToTen 
    {
    public BackgroundWorker bw = new BackgroundWorker();
    public CountToTen()
    {
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    }
    
    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        //Do your Stuff
    }
    }
    

Upvotes: 0

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236228

This is a subscription to RunWorkerCompleted event of BackgroundWorker. You can do this either with anonymous method, or with named method. Also you can remove delegate type declaration this way:

worker.RunWorkerCompleted += (o, args) => 
{
    // raise HandleWorkerEvent if there is any subscriber exists
    if (HandleWorkerEvent != null)    
        HandleWorkerEvent(this, e);

    worker.Dispose();
};

With named method this will look like

worker.RunWorkerCompleted += Worker_RunWorkerCompleted;

Handler:

void Worker_RunWorkerCompleted(object o, RunWorkerCompletedEventArgs args)
{
    if (HandleWorkerEvent != null)    
        HandleWorkerEvent(this, e);

    ((BackgroundWorker)o).Dispose();
}

BTW I think it's better to have class, which will only have counting to ten logic. Create BackgroundWorker on your form, and use this class in DoWork event handler. Also form will dispose all its components.

Upvotes: 2

chameleon
chameleon

Reputation: 1004

You can subscribe to RunWorkerCompleted event of your BackgroundWorker directly, but it depends on your business logic and architecture.

Upvotes: 0

Related Questions