Reputation: 1627
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
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
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
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
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
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