简体   繁体   English

调试与发布C#代码

[英]Debug vs Release C# code

I have the following code: 我有以下代码:

 public static void Main(string[] args)
    {
        bool isComplete = false;

        var t = new Thread(() =>
        {
            int i = 0;
            while (!isComplete) i += 0;
        });

        t.Start();

        Thread.Sleep(500);
        isComplete = true;
        t.Join();
        Console.WriteLine("complete!");

    }

The program will hung in release mode and will give an output in debug mode ("complete!"). 程序将挂起在释放模式下,并以调试模式提供输出(“完成!”)。

What is the reason for that? 这是什么原因?

Thanks. 谢谢。

The value of the variable isComplete is most likely being loaded into a register in your release build to avoid the round-trip to read value from memory in the while loop. 变量isComplete的值很可能被加载到发布版本中的寄存器中,以避免在while循环中从内存中读取值的往返。

Therefore, the loop will not "detect" when the value of isComplete is changed to true. 因此,当isComplete的值更改为true时,循环将不会“检测”。

You need to indicate to the compiler that this variable is volatile : essentially telling the system to not make assumptions based on code executing in the current thread whether or not this memory changes (ie, some other thread or process might change it). 您需要向编译器指出此变量是volatile :实质上告诉系统不要根据当前线程中执行的代码做出假设,无论此内存是否发生更改(即某些其他线程或进程可能会更改它)。

See this SA answer for some details: 有关详细信息,请参阅此SA答案:

How do I Understand Read Memory Barriers and Volatile - StackOverflow 我如何理解读取内存障碍和易失性 - StackOverflow

If you want to dig even deeper into memory and concurrency, then here is an excellent article by Fabian Giesen about cache coherency in multi-core systems: 如果你想深入研究内存和并发性,那么这是Fabian Giesen关于多核系统中缓存一致性的优秀文章:

Cache coherency primer 缓存一致性引物

Atomic operations and contention 原子操作和争用

Here are good reasons why you should just use a lock unless you know what you are doing: 除非您知道自己在做什么,否则以下是使用锁定的好理由:

Volatile keyword usage vs Lock - StackOverflow 易失性关键字使用与锁定 - StackOverflow

Here is MSDN doc on Volatile.Read method: 这是关于Volatile.Read方法的MSDN doc:

Volatile.Read Method() Volatile.Read方法()

Note that without some more detailed explanation (see above SA thread, or google) of the terms, the description in the MSDN documentation can be hard to translate into what is actually going on. 请注意,如果没有更详细的说明(参见上面的SA主题或谷歌),MSDN文档中的描述可能很难转化为实际发生的情况。

Here is the MSDN doc on volatile keyword: 这是关于volatile关键字的MSDN doc:

volatile (C# Reference) volatile(C#参考)

In C# this keyword will use a half-fence (as far as I know); 在C#中,这个关键字将使用半栅栏(据我所知); you will also find this keyword in C for example, but there it only affects compiler optimizations (does not insert a memory barrier) as it was originally intended for reading memory-mapped I/O. 例如,你也可以在C中找到这个关键字,但它只影响编译器优化(不插入内存屏障),因为它最初用于读取内存映射的I / O.

Example : 示例

        bool isComplete = false;

        var t = new Thread(() =>
        {
            int i = 0;
            while (!Volatile.Read(ref isComplete)) i += 0;
        });

        t.Start();

        Thread.Sleep(500);
        isComplete = true;
        t.Join();
        Console.WriteLine("complete!");

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM