简体   繁体   English

发布和调试之间的区别?

[英]Difference between Release and Debug?

I get an very strange behaviour when I change my Visual Studio 2010 config from Debug to Release:当我将我的 Visual Studio 2010 配置从调试更改为发布时,我得到了一个非常奇怪的行为:

I have a BackgroundWorker : _bg , in the DoWork I have:我有一个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.)

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.ProgressChanged中,我有一个MessageBox ,在用户交互之后, iswaiting将设置回 false, _bg DoWork程序将继续。

 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 .当我从 Visual Studio 运行它或在调试模式下构建时,所有这些都工作得很好,但是当我将它构建到Release时,我永远不会退出while(iswaiting)循环,尽管我可以从日志中看到iswaiting已经设置回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 iswaiting in release mode, you need a memory barrier in place.为了在发布模式下安全地“看到” iswaiting中的变化,您需要一个适当的内存屏障。

The simplest way to "fix" this would be to mark iswaiting as volatile : “修复”这个问题的最简单方法是将iswaiting标记为volatile

volatile bool iswaiting;

That being said, "spinning" like this will completely consume one CPU core.也就是说,像这样“旋转”将完全消耗一个 CPU 内核。 A much better approach would be to use a ManualResetEvent to signal that you can continue.更好的方法是使用ManualResetEvent来表示您可以继续。

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

Then, instead of using iswaiting, you'd do:然后,您可以不使用 iswaiting,而是:

_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.这样做的好处是阻塞时不会消耗 CPU,也不必自己担心内存障碍。

So your problem is likely that you are using a boolean field, and you haven't marked it as volatile .所以你的问题很可能是你正在使用一个布尔字段,并且你没有将它标记为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.但是,将字段标记为volatile在这里并不是一个好主意。 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 .一种方法是使用ManualResetEventSemaphore

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. doWork 方法最好在触发后不关心进度更改事件。

A much better approach would be to use a Semaphore signal that you can continue.更好的方法是使用可以继续的信号量信号。

private Semaphore semaphore = new Semaphore(1, 1000);
semaphore.WaitOne();

and after you want to release在你想释放之后

semaphore.Release();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调试和发布之间的C#区别 - C# difference between Debug and Release Debug和Release之间有(性能)差异吗? - Is there any (performance) difference between Debug and Release? Bin / Debug和Bin / Release之间的区别 - Difference between Bin/Debug and Bin/Release 异常堆栈调试和发布模式之间的跟踪差异 - Exception Stack Trace difference between Debug and Release mode C#XNA Visual Studio:“发布”和“调试”模式之间的区别? - C# XNA Visual Studio: Difference between “release” and “debug” modes? 在“释放”模式(“优化”处于启用状态)上的“调试”与在“调试”模式下的“调试”之间有什么区别? - What is the difference between DEBUG on in Release Mode(while Optimize is on) and Debugging in Debug Mode? 调试和发布之间的行为不同 - Different behaviour between Debug and Release 运行时和调试之间的区别 - Difference between runtime and debug 为什么C++ Debug版和Release版的性能差别很大,而C#没有? - Why is there a huge difference in performance between the C++ Debug version and the Release version, but not C#? 处理不在GAC中的.dll在DEBUG和Release之间移动 - Handling .dll not in GAC moving between DEBUG and Release
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM