6

I know from the codeing guidlines that I have read you should not do

for (int i = 0; i < 5; i++) 
{ 
    Task.Factory.StartNew(() => Console.WriteLine(i));
}
Console.ReadLine();

as it will write 5 5's, I understand that and I think i understand why it is happening. I know the solution is just to do

for (int i = 0; i < 5; i++) 
{ 
    int localI = i;
    Task.Factory.StartNew(() => Console.WriteLine(localI));
}
Console.ReadLine();

However is something like this ok to do?

foreach (MyClass myClass in myClassList) 
{ 
    Task.Factory.StartNew(() => myClass.DoAction());
}
Console.ReadLine();

Or do I need to do the same thing I did in the for loop.

foreach (MyClass myClass in myClassList) 
{ 
    MyClass localMyClass = myClass;
    Task.Factory.StartNew(() => localMyClass.DoAction());
}
Console.ReadLine();
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431

1 Answers1

6

It's absolutely the same problem with foreach. The following:

foreach (MyClass myClass in myClassList) 
{ 
    Task.Factory.StartNew(() => myClass.DoAction());
}

will most probably always invoke the DoAction method on the last element of the list, which could be fixed like this:

foreach (MyClass myClass in myClassList) 
{ 
    MyClass localMyClass = myClass;
    Task.Factory.StartNew(() => localMyClass.DoAction());
}

But instead of relying on local variables I would recommend you the following:

for (int i = 0; i < 5; i++)
{
    Task.Factory.StartNew(localI => Console.WriteLine(localI), i);
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I don't really care about the for case, I just copied the code from http://download.microsoft.com/download/B/C/F/BCFD4868-1354-45E3-B71B-B851CD78733D/ParallelProgramsinNET4_CodingGuidelines.pdf I really just want to know about the foreach case. Also my code is a little more complicated than what I posted. look at the previous revision to see what I am really doing. – Scott Chamberlain May 28 '10 at 13:19
  • It's the same thing with `foreach`. – Darin Dimitrov May 28 '10 at 13:24
  • And not only is it the same between for and foreach, but between value and reference types. http://stackoverflow.com/questions/235455/access-to-modified-closure I just spent the better part of a day trying to debug one of these until a colleague pointed out my error. – Calvin Fisher Jun 09 '11 at 20:55
  • @DarinDimitrov Would you please check this one: http://stackoverflow.com/questions/15847329/parallel-foreach-vs-foreach-and-task-in-local-variable – Saeid Apr 06 '13 at 06:34