C#中,为什么值类型的局部变量被不同线程共享

tae*_*ong 1 c# stack

据我了解,值类型存储在堆栈区域内存中,但某些情况除外,例如作为引用类型字段成员包含的值类型。

我知道线程有不同的独特堆栈区域。

然而,代码执行结果显示a、b、c线程共享count变量并将值增加到300。

怎么了?

                public void Test()
        {
            int count = 0;
            Thread a = new Thread(delegate ()
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++count}");
                }
            });
            a.Start();

            Thread b = new Thread(delegate ()
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++count}");
                }
            });
            b.Start();

            Thread c = new Thread(delegate ()
            {
                for (int i = 0; i < 100; i++)
                {
                    Console.WriteLine($"Thread ID : {Thread.CurrentThread.ManagedThreadId}, Count : {++count}");
                }
            });
            c.Start();
        }
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Mar*_*ell 5

据我了解,值类型存储在堆栈区域内存中,但某些情况除外,例如作为引用类型字段成员包含的值类型。

在本例中,count是一个捕获的变量,编译器通过将其设为堆上对象的字段来精确实现该变量。您可以通过编译和反编译代码来看到这一点,如下所示- 特别是:

    [CompilerGenerated]
    private sealed class <>c__DisplayClass0_0
    {
        public int count;
Run Code Online (Sandbox Code Playgroud)

这就是编译器实现在所有委托用法之间共享的值所需的语义的方式 - 在本例中,这恰好意味着“线程之间”(尽管这不是必要的部分)。