用于共享内部变量的 C# 并行
本文关键字:并行 变量 共享 内部 用于 | 更新日期: 2023-09-27 18:33:25
嗨,我正在处理以下代码:
Parallel.For(1, residRanges.Count, i =>
{
int count = 0;
List<double> colAList = new List<double>();
List<double> colBList = new List<double>();
for (int x = 0; x < residErrorData.Count; x++)
{
foreach (pricateConnection in residErrorData[x].connList)
{
if (residRanges[i].connection == nc.connection)
{
colAList.Add(residErrorData[x].residualError);
colBList.Add(nc.freq);
count = count + 1;
}
}
}
colA = new double[count];
colB = new double[count];
for (int j = 0; j < count; j++)
{
colA[j] = colAList[j];
colB[j] = colBList[j];
}
residRangeError tempresid = residRanges[i];
tempresid = fitResid(tempresid, colA, colB);
residRanges[i] = tempresid;
residRanges[i].n = count;
}
});
如果我不使用并行类,我的值似乎是准确的,但是当我出于某种原因使用并行类时,它会混淆 colA 和 colB 的值。它在线程之间混合它们。 我对并行处理相当陌生,但我一直在四处寻找,似乎找不到任何解决方案。 有谁知道为什么程序似乎在线程之间共享变量?
我知道代码并不理想,我一直在尝试不同的事情来找出出了什么问题。 我目前并不一定要优化它,而是要理解为什么不同循环中的变量没有保持独立。
residRanges[] 是类项的列表。 使用它的 for 循环似乎获得了正确的值,它们只是开始混淆哪些值在 Parallel.For 中运行时会去哪里。
感谢您的任何帮助! 我真的可以用它!
(重新发布作为甜蜜,甜蜜业力的答案)
您的代码看起来好像 colA
和 colB
是在 lambda 的作用域之外声明的,这意味着变量引用可以引用不同的数组对象,因为不同的线程同时运行(例如,线程 0 会更改colA
而线程 1 在 for j < count
循环内。
将 colA
和 colB
的声明移动到 lambda 内部:
...
Double[] colA = new double[count];
Double[] colB = new double[count];
for (int j = 0; j < count; j++)
...
但是,我看到除了将它们用作fitResid
函数的值持有者之外,您实际上并没有对colA
和colB
做任何有用的事情,您可以通过以下方式简化这一点:
- 将
fitResid
函数签名更改为接受IList<Double>
而不是Double[]
将
fitResid
函数调用更改为分别传入colAList
和colBList
传入,这将通过消除不必要的复制和内存分配来加快代码速度:... residRanges[i] = fitResid( residRanges[i], colAList, colBList ); residRanges[i].n = count; ...