c# - .NET 4.5 并行处理和 for 循环

标签 c# parallel-processing task-parallel-library

我正在尝试创建一个取决于可用处理器数量的任务列表。我有一个 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。

如有任何帮助,我们将不胜感激。

最佳答案

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

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

(我还建议您将 generateNewList 重命名为 GenerateNewList 以符合 .NET 命名约定。)

关于c# - .NET 4.5 并行处理和 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14273091/

相关文章:

c# - 并行化一个非常紧密的循环

c# - .NET 4 中的 TaskCreationOptions.DenyChildAttach

c# - 将短语翻译与 String.Format 集成

c# - 创建 n*m 值的所有组合

并发内核启动示例 - CUDA

c# - TPL数据流: Cancellations

c# - 使用 TPL 的 Parallel.ForEach 时跟踪进度

c# - 不能使用 lambda 表达式作为动态调度操作的参数

c# - Asp.Net 将 Dictionary<string, object> 反序列化为对象

worker 中的 Python 多处理和处理异常