C# · 12月 24, 2021

c# – 发布和调试之间的区别?

当我将Visual Studio 2010配置从Debug更改为Release时,我得到一个非常奇怪的行为:

我有一个BackgroundWorker:_bg,在DoWork中我有:

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.)

在ProgressChanged中我有一个Message@R_974_2419@,在用户交互之后,iswaiting将被设置为false并且_bg DoWork程序将继续.

void _bg_ProgressChanged(object sender,ProgressChangedEventArgs e) { //my other part of code…….. result = Microsoft.Windows.Controls.Message@R_974_2419@.Show(“Question”,”Title”,Message@R_974_2419@Button.YesNoCancel,Message@R_974_2419@Image.Warning); iswaiting=false; log(iswaiting.toString()); }

当我从Visual Studio运行它或构建在调试模式时,所有这些都能很好地工作,但是当我将它构建到Release时,我永远不会离开while(等待)循环,虽然我可以从日志中看到iswaiting已经设置回到假.

编辑:

更好的方式是非常欢迎!

解决方法 这可能是由于线程优化造成的.为了安全地“看到”在释放模式下等待的变化,您需要一个内存屏障.

“修复”这个的最简单方法是将等待标记为volatile:

volatile bool iswaiting;

话虽如此,像这样“旋转”将完全消耗一个cpu核心.更好的方法是使用ManualResetEvent来表示您可以继续.

// Add:private ManualResetEvent allowProgress = new ManualResetEvent(false);

然后,你不会使用等待,而是:

_bg.ReportProgress(1,filePath);allowProgress.WaitOne(); // This will block until it’s set

要允许此操作继续,请使用:

result = Microsoft.Windows.Controls.Message@R_974_2419@.Show(“Question”,Message@R_974_2419@Image.Warning); allowProgress.Set();

这里的优点是,在您被阻止时不会消耗cpu,并且您不必担心自己的内存障碍.