If I have this:
public string DoSomething(string arg)
{
string someVar = arg;
DoStuffThatMightTakeAWhile();
return SomeControl.Invoke(new Func<string>(() => someVar));
}
And this method can be called concurrently from multiple threads, and 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 and consequently, DoSomething
return the second version of someArg
on both calls, or will one someVar
exist for each thread?
Edit I think my Action
should have been a Func
so edited it.
As said, each thread hitting
DoSomething
is creating a separatesomeVar
on its stack, and therefore no thread has any effect on another'ssomeVar
.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:
Demonstrates this.
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
will capture it's own value of
someVar
.Edit
I was simply wrong saying that, as Eric pointed. See his answer for correct explanation.
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:
No. There is a new "someVar" for each activation of DoSomething.
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.