Vikram
Vikram

Reputation: 1627

Backgroundworker's RunWorkerCompleted event is firing even before completing the work

I am using the BackgroundWorker thread to perform a long task(basically reading a big xml file). For the first time the worker works fine as desired, but if I upload a second xml file, using the same background worker it works fine sometimes but most of the time the Backgroundworker's RunWorkerCompleted is fired even before the DoWork event. Some of the code is displayed below

    private void openFile_Click(object sender, RoutedEventArgs e)
    {
          // Code removed for brevity
  worker = new BackgroundWorker();
            worker.RunWorkerAsync();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
       }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        DataImport();
        //worker.Dispose();
        //worker.Disposed += new EventHandler(worker_Disposed);
        //worker.DoWork -= worker_DoWork;
        //worker.RunWorkerCompleted -= worker_RunWorkerCompleted;
        //worker = null;
        //GC.Collect(GC.GetGeneration(worker), GCCollectionMode.Forced);
    }

worker is a globally defined variable. What is wrong here I am not getting. Kindly help

Upvotes: 3

Views: 10691

Answers (5)

Cihangir Ozdemir
Cihangir Ozdemir

Reputation: 21

If you Call another async function in your BackgroundWorker _DoWork event,

like;

    private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        somethingsToDoAsync();
        // somethingsToDoAsync() function is to ASYNC 
    }

_RunWorkerCompleted fires even before completed _Dowork event.

Change another function to not async.

Upvotes: 0

Eduardo Arruda
Eduardo Arruda

Reputation: 11

As said in https://stackoverflow.com/a/16809596/8029935, you can be blindly assuming that the worker has finished the job and produced a result when DoWork Method dies from an exception. Which is caught by BackgroundWorker and passed to the RunWorkerCompleted event handler as the e.Error property.

So, I suggest you must check that property using a try/catch statement.

Upvotes: 0

Mukesh Kumar
Mukesh Kumar

Reputation: 2376

you should check first that background worker is busy or not, using this....

        backgroundWorker1.DoWork += backgroundWorker1_DoWork;
        backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
        if (backgroundWorker1.IsBusy)
        {
            backgroundWorker1.CancelAsync();
        }
        else
        {
            backgroundWorker1.RunWorkerAsync();

        }

Upvotes: 2

Vishal
Vishal

Reputation: 624

It should be like this:

worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;

worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.ProgressChanged += 
    new ProgressChangedEventHandler(worker_ProgressChanged);
worker.RunWorkerCompleted += 
    new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

worker.RunWorkerAsync();

RunWorkerAsync should be called after subscribing to the DoWork and RunWokerCompleted events.

Upvotes: 2

sloth
sloth

Reputation: 101032

You should add the DoWork-event handler (and all other event handler, too) before calling RunWorkerAsync().

Otherwise, it could happen that RunWorkerAsync does practically nothing.

Upvotes: 9

Related Questions