1

我正在尝试创建一个取决于可用处理器数量的任务列表。我有一个 for 循环,它的行为似乎很奇怪。我知道 javascript 中的闭包概念,似乎这里可能会发生类似的事情:

 var tasks = new Task[Environment.ProcessorCount]; 
 for(int x = 0; x < Environment.ProcessorCount; x ++)
 {
      tasks[x] = Task.Run(() => new Segment(SizeOfSegment, x * SizeOfSegment, listOfNumbers).generateNewList());
 }

我发现当我在 for 循环中换行时,变量 x 似乎是正确的,所以它从 0 开始到 3 结束(处理器数量为 4)。但是,当我在 Segment 的构造函数中放置断点时,我发现在返回调用堆栈时 x 实际上是 4。

任何帮助将不胜感激。

4

1 回答 1

7

x在你的 lambda 表达式中捕获 - 但是你有一个变量 x在循环过程中改变值,所以当你的任务实际运行时,它很可能有不同的值。您需要在循环内创建变量的副本,在每次迭代时创建一个新的“变量实例”。然后您可以安全地捕获变量:

for(int x = 0; x < Environment.ProcessorCount; x ++)
{
    int copy = x;
    tasks[x] = Task.Run(() => new Segment(SizeOfSegment,
                                          copy * SizeOfSegment,
                                          listOfNumbers).generateNewList());
}

(我还建议您重命名generateNewListGenerateNewList符合 .NET 命名约定。)

于 2013-01-11T06:48:29.927 回答