Architect or Cobbler?
Good code starts with good design

BackgroundWorker race condition bug?

Saturday, December 23, 2006

As I said the other day, I'm writing a new course (actually updating an existing one), and I've been writing practicals for the delegates.  As part of this I wrote an exercise that used BackgroundWorker to spawn a thread that searches for files on the file system.  Occasionally the program would fail with a System.InvalidOperationException with the message "This operation has already had OperationCompleted called on it and further calls are illegal."  I realised straight away that my call to ReportProgress was causing the ProgressChanged event to be raised after the BackgroundWorker had raised the RunWorkerCompleted event.  I suspected my code and banged around for ages trying to find the problem, but it actually appears to be a bug in the implementation.  If you raise a ReportProgress at roughly the same time the thread completes, you have a race, and one that the RunWorkerCompleted will nearly always win, as it doesn't have to issue a BeginInvoke.  In my case I was reporting progress every 23 files (don't ask it seemed a good number), and in cases where the search returns multiples of 23, then the RunWorkerCompleted would be raised at the same time as the ReportProgress and I'd get a race condition.

For now I've added a sleep at the end of my DoWork event handler to prevent it from finishing before my last ReportProgress has been actioned.  Does anyone have any better ideas?


# posted by James @ 4:29 PM   2 comments Comments: Interestingly I found the same problem. My worker does a bit of step by step computing in a datatable and tries to write the result out to a database.
Unpredictably, the program drops a few results now and then when it reaches the end of the table will trying to write out the data.
The problem with the sleep method is that I can't make up a proper sleeping value. I'd rather find a way to tell the thread to stop - write out the stuff - go back to work. Have you found an option since 2006?
Thanks
# posted by Anonymous Anonymous @ 9:28 PM   Check IsBusy before calling ReportProgress.
# posted by Anonymous Anonymous @ 8:20 PM   Post a Comment

<< Main blog page
This page is powered by Blogger. Isn't yours?