Foreach循环和任务

6

根据我所阅读的编码指南,您不应该这样做。

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

由于它会写入5个5,我理解了这一点,也知道为什么会发生这种情况。我知道解决方法就是:

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

这样做可以吗?
foreach (MyClass myClass in myClassList) 
{ 
    Task.Factory.StartNew(() => myClass.DoAction());
}
Console.ReadLine();

或者我需要做与for循环中相同的事情。
foreach (MyClass myClass in myClassList) 
{ 
    MyClass localMyClass = myClass;
    Task.Factory.StartNew(() => localMyClass.DoAction());
}
Console.ReadLine();
1个回答

6

对于 foreach 来说,它也存在完全相同的问题。以下是示例:

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

最有可能总是调用列表中的最后一个元素上的DoAction方法,可以通过以下方式进行修复:

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

但是,我建议您不要仅仅依赖于本地变量,而是使用以下方法:

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

我并不在意for循环的情况,我只是从http://download.microsoft.com/download/B/C/F/BCFD4868-1354-45E3-B71B-B851CD78733D/ParallelProgramsinNET4_CodingGuidelines.pdf复制了代码。我真正想知道的是foreach循环的情况。此外,我的代码比我发布的要复杂一些。请查看之前的版本以了解我真正在做什么。 - Scott Chamberlain
使用 foreach 也是同样的道理。 - Darin Dimitrov
不仅在for和foreach之间相同,而且在值类型和引用类型之间也是如此。https://dev59.com/5XVC5IYBdhLWcg3woCjN 我花了一整天的时间来调试其中一个问题,直到我的同事指出了我的错误。 - Calvin Fisher
@DarinDimitrov,您能否检查一下这个问题:http://stackoverflow.com/questions/15847329/parallel-foreach-vs-foreach-and-task-in-local-variable - Saeid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接