I get an very strange behaviour when I change my Visual Studio 2010 config from Debug to Release:
I have a BackgroundWorker: _bg, in the DoWork I have:
iswaiting = true;
_bg.ReportProgress(1, filePath);
while (iswaiting)
{
;
}
//My other part of code (EDIT: something do to with the `result` I get from the user.)
in the ProgressChanged I have a MessageBox and after the user interaction, iswaiting will be set back to false and the _bg DoWork program will continue.
void _bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//my other part of code........
result = Microsoft.Windows.Controls.MessageBox.Show("Question" ,"Title", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
iswaiting=false;
log(iswaiting.toString());
}
All of these works very well when I run it from Visual Studio or build in Debug mode, but when I build it to Release, I never get out of the while(iswaiting) loop, although I can see from the log iswaiting is already set back to false.
EDIT:
Better way of doing this is more than welcome!!
This is likely due to threading optimizations. In order to safely “see” the change in
iswaitingin release mode, you need a memory barrier in place.The simplest way to “fix” this would be to mark
iswaitingasvolatile:That being said, “spinning” like this will completely consume one CPU core. A much better approach would be to use a
ManualResetEventto signal that you can continue.Then, instead of using iswaiting, you’d do:
To allow this to continue, use:
The advantage here is that you won’t consume CPU while you’re blocked, and you don’t have to worry about the memory barriers yourself.