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!!
Debug Mode: In debug mode the application will be slow. Release Mode: In release mode the application will be faster. Debug Mode: In the debug mode code, which is under the debug, symbols will be executed. Release Mode: In release mode code, which is under the debug, symbols will not be executed.
Debug mode and Release mode are different configurations for building your . Net project. Programmers generally use the Debug mode for debugging step by step their . Net project and select the Release mode for the final build of Assembly file (. dll or .exe).
Visual Studio projects have separate release and debug configurations for your program. You build the debug version for debugging and the release version for the final release distribution. In debug configuration, your program compiles with full symbolic debug information and no optimization.
Major differences are the debug apk and the release apk: For debug builds the apk will be signed with the default debug signing keys with debug flag enabled. For release apk you will have to explicitly specify the apk to sign with and the debug flag will be turned off so that it cannot be debugged.
This is likely due to threading optimizations. In order to safely "see" the change in iswaiting
in release mode, you need a memory barrier in place.
The simplest way to "fix" this would be to mark iswaiting
as volatile
:
volatile bool iswaiting;
That being said, "spinning" like this will completely consume one CPU core. A much better approach would be to use a ManualResetEvent
to signal that you can continue.
// Add:
private ManualResetEvent allowProgress = new ManualResetEvent(false);
Then, instead of using iswaiting, you'd do:
_bg.ReportProgress(1, filePath);
allowProgress.WaitOne(); // This will block until it's set
To allow this to continue, use:
result = Microsoft.Windows.Controls.MessageBox.Show("Question" ,"Title", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
allowProgress.Set();
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.
So your problem is likely that you are using a boolean field, and you haven't marked it as volatile
. Because of this, certain optimizations (often only applied in release mode) can result in both threads accessing a copy of the field that is local to their thread (possibly on the cache of their core of the processor, for example).
However, marking the field volatile
isn't really a good idea here. You have a more fundamental problem in that you're performing a spinwait, which is virtually always a bad idea. You should use a method that actually pauses the thread until it is supposed to continue. One way would be to use a ManualResetEvent
or a Semaphore
.
Looking at your code, what you're waiting on is for the user to dismiss a message box fired in the progress changed event. I would say that, rather than having this in the progress changed event, you should simply include it in the actual "do work" event. It is desirable for the doWork method to not care about the progress changed event once it's fired.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With