Search code examples
c#wpfmultithreadingbackgroundworker

C# Backgroundworker data invalid - thread issue?


please take a look at my issue:

I have logic developed that will run over a long period of time. While running the logic, I want to report the status to a progress bar. Great! So i used background worker:

_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
_backgroundWorker.ProgressChanged += new  ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.RunWorkerAsync();

within backgroundWorker_Dowork, I have the logic that does the job. I also declare a timer that gets invoked every 50ms to report status.(within backgroundWorker_DoWork):

timer.Elapsed += (senderr, ee) => timer_Elapsed();
_timer.Interval = 50;

within timer_Elapsed, I update the UI control by calling _backgroundWorker.ReportProgress(0); The reason I dont call ReportProgress within backgroundWorker_DoWork is because although my code takes a while, the while loop I used to do my work is extremely fast. If I call ReportProgres at the end of my while loop, then the same non-responsive type of UI problem occurs.

Now my issue is when processing little data, when timer_Elapsed is called, all the variables and data are 0 and null. and I cant seem to figure out why.. I have extensive experience with multi threaded programming but C# masks everything and I have no clue which thread has what data...

the timer is then diposed within the backgroundWorker_DoWork after the long running logic is completed.

any idea on why those data are invalid? any hint would be appreciated.


Solution

  • You don't show all your code, but my understanding of your description is that timer.Elapsed runs on a different thread than your background worker, hence you have a race condition.

    Also, your remark about "when processing little data" makes me think that your timer.Elapsed is called after the background worker has already completed and you're not handling this case correctly.

    I would suggest that you report progress directly from the background worker. Just don't do it every iteration of your loop, just one out of 1000 (actual number should get chosen according to how fast your loop spins).