C#parallel用于共享内部变量

时间:2016-02-04 17:38:42

标签: c# multithreading parallel-processing

您好我正在处理以下代码:

            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中运行的地方。

感谢您的帮助!我真的可以用它!

1 个答案:

答案 0 :(得分:1)

(作为甜蜜,甜蜜的业力的回答)

您的代码看起来好像colAcolB在lambda的范围之外声明,这意味着变量引用可以引用不同的数组对象,因为不同的线程同时运行(例如,线程0会改变{{ 1}}而线程1在colA循环内。

for j < countcolA的声明移到lambda:

colB

但是,我发现您实际上并没有对... Double[] colA = new double[count]; Double[] colB = new double[count]; for (int j = 0; j < count; j++) ... colA执行任何有用的操作,除了将它们用作colB函数的值持有者之外,您可以通过以下方式简化:

  1. 将您的fitResid功能签名更改为接受fitResid而不是IList<Double>
  2. 将您的Double[]函数调用分别更改为fitResidcolAList,这将通过消除不必要的复制和内存分配来加速您的代码:

    colBList