Multithreading and closures in .NET Multithreading and closures in .NET multithreading multithreading

Multithreading and closures in .NET


There are a number of confusions in the answers here, mostly based upon the untruth that local variables are allocated "on the stack of the thread". This is both false and irrelevant.

It's false because the local variable may be allocated on some temporary pool or the long-term storage pool; even if it is allocated on a temporary pool, that need not be stack memory; it could be a register. It's irrelevant because who cares what pool the storage is allocated on?

The relevant fact is that a top-level local variable is allocated per method activation. More generally, a local variable in a block is allocated once per the block being entered; a local variable declared in the body of a loop, for example, is allocated every time the loop goes around.

So, let's consider your question:

This method can be called concurrently from multiple threads. If one thread is stuck at DoStuffThatMightTakeAWhile, and then a second thread calls DoSomething with a different arg, will this change the value of someVar for all threads?

No. There is a new "someVar" for each activation of DoSomething.

will one someVar exist for each thread?

One "someVar" will exist for each activation. If a thread does exactly one activation then there will be exactly one someVar per thread; if a thread does a million activations then there will be a million of them.

That said, Jon Hanna's answer is also correct: if you make a delegate which both reads and writes a local variable, and you hand that delegate out to multiple threads, then all the activations of the delegate share the same local variable. There is no magical thread safety created for you; if you want to do that then you are responsible for ensuring thread safety.


Local variables stored in the current thread's stack, so each thread will have its own stack and each own someVar variable in it.

Since it would be different values in each thread

new Action(() => someVar)); 

will capture it's own value of someVar.

Edit

I was simply wrong saying that, as Eric pointed. See his answer for correct explanation.


As said, each thread hitting DoSomething is creating a separate someVar on its stack, and therefore no thread has any effect on another's someVar.

It is worth noting though, that if a local is captured in a closure and there is multi-threading initiated in that scope, that this can indeed cause different threads to affect the values each other sees, even in the case of value types (which we would normally think of as not something that another method can affect - in this way closures are not like class methods:

public static void Main(string[] args){    int x = 0;    new Thread(() => {while(x != 100){Console.WriteLine(x);}}).Start();    for(int i = 0; i != 100; ++i)    {        x = i;        Thread.Sleep(10);    }    x = 100;    Console.ReadLine();}

Demonstrates this.