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