You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Parallel.For结合ConcurrentBag使用疑似非线程安全问题咨询

你遇到的「ConcurrentBag疑似收到其他线程数据」的问题和ConcurrentBag本身无关,该集合是标准线程安全实现,你的代码存在多处语法、逻辑错误,具体问题如下:

问题排查

  • 语法错误
    • if判断语句多写了一个冗余左括号,没有对应右括号闭合,代码无法正常编译
    • 条件判断中访问xSource数组未指定索引i,直接对整个数组和double类型做减法运算,属于类型错误,得到的计算结果完全不符合预期,导致大量不符合条件的数值被添加到集合中,这是你误以为拿到其他线程数据的核心原因,正确写法应为访问xSource[i]
  • 方法调用错误
    如果你用到的Mat.Abs是EmguCV等第三方库提供的矩阵处理方法,传入两个double的差值作为参数,要么会直接编译报错,要么会产生非预期的计算结果,导致判断条件完全失效,建议替换为System.Math.Abs处理double类型的绝对值计算。
  • 性能优化建议
    海量数据处理场景下,每次迭代都调用线程安全集合的Add方法会产生大量锁开销,推荐使用Parallel.For的本地线程状态重载,每个线程先操作本地普通List,所有迭代完成后再合并结果,既可以避免锁竞争,性能也远高于直接操作ConcurrentBag。

修正后代码示例

public static void GetNearXvalues(double deltaX, double xCenter, double[] xSource, out double[] xNear)
{
    var globalResult = new List<double>();

    // 使用带本地状态的Parallel.For重载降低锁开销
    Parallel.For<List<double>>(
        0,
        xSource.Length,
        // 每个工作线程初始化本地存储容器
        () => new List<double>(),
        // 单迭代处理逻辑,仅操作本地List无锁开销
        (i, state, localList) =>
        {
            if (Math.Abs(xCenter - xSource[i]) < deltaX)
            {
                localList.Add(xSource[i]);
            }
            return localList;
        },
        // 线程结束后合并本地结果到全局容器,仅此处需要加锁
        localList =>
        {
            lock (globalResult)
            {
                globalResult.AddRange(localList);
            }
        }
    );

    xNear = globalResult.ToArray();
}

内容的提问来源于stack exchange,提问作者Wolfgang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 14:54:02