In c#, why is local variable of value type shared by different threads

Advertisements

I understand that the value type is stored in the stack area memory, except for some situations, such as the value type included as a reference type field member.

And I know that threads have different unique stack areas.

However, code execution results show that the a, b, and c threads share the count variable and increase the value to 300.

What’s wrong?

                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();
        }

enter image description here

>Solution :

I understand that the value type is stored in the stack area memory, except for some situations, such as the value type included as a reference type field member.

In this case, count is a captured variable, which the compiler implements precisely by making it a field on an object on the heap. You can see this by compiling and decompiling the code, like this – in particular:

    [CompilerGenerated]
    private sealed class <>c__DisplayClass0_0
    {
        public int count;

This is how the compiler achieves the required semantic of the value being shared between all delegate usages – which in this case happens to mean "between threads" (although that isn’t a necessary part).

Leave a ReplyCancel reply