C#编译器优化和volatile关键字

Céd*_*non 3 .net c# multithreading volatile

我已经阅读了一些关于volatile没有此关键字的关键字和行为的帖子

我特别测试了C#中说明volatile关键字的使用答案的代码.运行时,我会在发布模式下观察异常行为,不附加调试器.到那时为止,没有问题.

所以,据我所知,以下代码永远不会退出.

public class Program
{
    private bool stopThread;

    public void Test()
    {
        while (!stopThread) { }  // Read stopThread which is not marked as volatile
        Console.WriteLine("Stopped.");
    }


    private static void Main()
    {
        Program program = new Program();

        Thread thread = new Thread(program.Test);
        thread.Start();

        Console.WriteLine("Press a key to stop the thread.");
        Console.ReadKey();

        Console.WriteLine("Waiting for thread.");
        program.stopThread = true;

        thread.Join();  // Waits for the thread to stop.
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么退出?即使在发布模式下,没有调试器?

更新

修改了C#中对volatile关键字的使用的代码.

private bool exit;

public void Test()
{
    Thread.Sleep(500);
    exit = true;
    Console.WriteLine("Exit requested.");
}

private static void Main()
{
    Program program = new Program();

    // Starts the thread
    Thread thread = new Thread(program.Test);
    thread.Start();

    Console.WriteLine("Waiting for thread.");
    while (!program.exit) { }
}
Run Code Online (Sandbox Code Playgroud)

在没有调试器的情况下,在发布模式下,该程序不会退出.

Jon*_*eet 10

所以,据我所知,以下内容永远不会退出.

不,它可以停止.它不能保证.

例如,它不会停留在我正在运行的机器上 - 但同样我可以在另一台机器上尝试完全相同的可执行文件,它可能表现良好.它将取决于它运行的CLR使用的确切内存模型语义.这将受到底层架构的影响,甚至可能使用正确的CPU.

重要的是要注意,不是C#编译器决定如何处理volatile字段 - C#编译器只是指示使用的元数据的波动性System.Runtime.CompilerServices.IsVolatile.然后,JIT可以在遵守相关合同方面找出其意义.