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

Parallel.ForEach与foreach运行结果不同:我的代码为何线程不安全?

问题原因

你写的Parallel实现不是线程安全的核心原因是存在共享变量的竞态条件,具体问题如下:

  • 你将int index变量声明在Parallel.ForEach循环的外部,并行执行的每个匿名委托都会捕获这个全局的index变量,所有线程共用同一个变量的内存地址,读写操作没有同步限制。
    举个实际的执行异常场景:
  1. 线程A计算出当前关键词的索引值为12,刚完成对index的赋值
  2. 还没等线程A执行indexes.Add(index)操作,线程B就把自己计算出的索引值102赋值给了同一个index变量
  3. 线程A后续执行Add操作时,存入集合的就是被覆盖后的102,而非自己计算的12,最终统计的最小值就会出错
  • 你用到的ConcurrentBag本身是线程安全的集合,写入操作没有问题,问题完全来自外部共享的index变量。而普通的foreach是单线程顺序执行,不存在同时改写index的情况,所以结果符合预期。
修复方案

将index变量的声明挪到Parallel.ForEach的委托内部,让每个并行任务使用自己独立的局部变量,即可解决线程安全问题,修复后代码如下:

ConcurrentBag<int> indexes = new();

switch (Case)
{
    case 1:
        Parallel.ForEach(KeywordTypes.GetImplementedNamedObjects(), inos =>
        {
            // 把index声明放到委托内部,每个线程有独立的变量副本
            int index = content.IndexOf($"/begin {inos}");
            index = index == -1 ? content.Length : index;
            indexes.Add(index);
        });
        int minIndex = indexes.Min();
        return minIndex;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:36:01