Difference between Release and Debug?

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.