In the two following snippets, is the first one safe or must you do the second one?
By safe I mean is each thread guaranteed to call the method on the Foo from the same loop iteration in which the thread was created?
Or must you copy the reference to a new variable ‘local’ to each iteration of the loop?
var threads = new List<Thread>(); foreach (Foo f in ListOfFoo) { Thread thread = new Thread(() => f.DoSomething()); threads.Add(thread); thread.Start(); }
–
var threads = new List<Thread>(); foreach (Foo f in ListOfFoo) { Foo f2 = f; Thread thread = new Thread(() => f2.DoSomething()); threads.Add(thread); thread.Start(); }
Update: As pointed out in Jon Skeet’s answer, this doesn’t have anything specifically to do with threading.
Edit: this all changes in C# 5, with a change to where the variable is defined (in the eyes of the compiler). From C# 5 onwards, they are the same.
Before C#5
The second is safe; the first isn’t.
With
foreach, the variable is declared outside the loop – i.e.This means that there is only 1
fin terms of the closure scope, and the threads might very likely get confused – calling the method multiple times on some instances and not at all on others. You can fix this with a second variable declaration inside the loop:This then has a separate
tmpin each closure scope, so there is no risk of this issue.Here’s a simple proof of the problem:
Outputs (at random):
Add a temp variable and it works:
(each number once, but of course the order isn’t guaranteed)