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

Parallel.For循环填充List元素数量不足的原因及解决方案

问题原因与解决方法

原因

List<T>不是线程安全的集合,它的Add方法内部包含多个非原子操作:比如检查内部数组容量、写入新元素、更新计数。当多个线程同时调用Add时,会触发竞态条件——例如两个线程同时读取当前的元素计数,然后都基于这个计数去写入新元素,导致其中一个元素的写入被覆盖;或者计数更新时出现错误,最终导致集合内的元素数量少于预期。

正确解决方法

方法1:使用线程安全集合ConcurrentBag<T>

ConcurrentBag<T>是.NET专门为并行场景设计的线程安全集合,适合这种多线程添加元素的场景:

var someBag = new ConcurrentBag<ListItem>();
Parallel.For(0, 1000000, _ =>
{
    var item = new ListItem();
    // some logic here
    someBag.Add(item);
});

System.Console.WriteLine(someBag.Count); // 输出1000000

如果最终需要List<T>类型,可以在并行操作结束后转换:

var someList = someBag.ToList();

方法2:用锁同步Add操作(不推荐)

虽然可以通过lock关键字确保Add操作的原子性,但这种方式会让并行操作退化为串行执行,完全失去Parallel.For的性能优势,仅适合极端场景:

var someList = new List<ListItem>();
var lockObj = new object();
Parallel.For(0, 1000000, _ =>
{
    var item = new ListItem();
    // some logic here
    lock (lockObj)
    {
        someList.Add(item);
    }
});

System.Console.WriteLine(someList.Count); // 输出1000000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:10:25