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

在Parallel.ForEach中共享List<T>是否需要同步?两种场景解析

Parallel.ForEach操作List的同步必要性分析

仅调用Add添加元素的场景

别侥幸,必须加同步或者换线程安全集合,List<T>完全不是线程安全的。

Add看着是个单一方法,但内部要做的事不少:检查当前数组容量够不够,不够就扩容;然后把元素放到对应位置,再更新Count字段。这些步骤没有原子性保障,多个线程并行执行时,会出现各种竞态问题:比如两个线程同时触发扩容,导致数组状态混乱;或者更新Count时互相覆盖,最后集合里的元素数量不对,甚至直接抛出IndexOutOfRangeException。

先Any读取再Add的场景

这个场景风险比单纯Add还高,绝对需要同步。

这里同时涉及了读(Any)和写(Add)操作,List<T>根本不支持多线程下的读写并发。当一个线程在执行Any遍历集合的时候,另一个线程可能正在修改内部数组(比如扩容、插入元素),轻则导致Any返回错误结果(比如集合有元素却返回false),重则直接抛出InvalidOperationException(提示集合已修改,无法枚举)。哪怕你觉得Any只是判断是否为空,它本质还是在遍历集合,只要遍历过程中集合被修改,就会出问题。

总结

不管是单纯写还是读写混合,只要是在Parallel.ForEach这种多线程并行场景下操作List<T>,都不能直接裸用。要么用lock之类的同步机制包裹操作,要么直接换成ConcurrentBag<T>、ConcurrentQueue<T>这类线程安全集合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 13:54:53