我有一个填充 List<T>
的主线程.此外,我创建了一个将在不同线程上执行的对象链,需要访问列表。原始列表生成后将永远不会被写入。我的想法是将列表传递为 IEnumerable<T>
到在其他线程上执行的对象,主要是为了不允许那些实现这些对象的人错误地写入列表。换句话说,如果保证不写入原始列表,多线程使用.Where
是否安全?或 foreach
在 IEnumerable 上?
如果原始集合从未更改,我不确定迭代器本身是否是线程安全的。
最佳答案
IEnumerable<T>
无法修改。那么什么可以是非线程安全的呢? (如果您不修改实际的 List<T>
)。
对于非线程安全,您需要写入和读取操作。
为每个 foreach
实例化“迭代器本身” .
编辑:我稍微简化了我的回答,但@Eric Lippert 添加了有值(value)的评论。 IEnumerable<T>
没有定义修改方法,但这并不意味着访问运算符是线程安全的( GetEnumerator
, MoveNext
等)最简单的例子: GetEnumerator
实现如下:
- 每次都返回
IEnumerator
的相同实例 - 重置它的位置
更复杂的例子是缓存。
这是一个有趣的观点,但幸运的是,我不知道有哪个标准类没有IEnumerable
的线程安全实现。 .
关于c# - IEnumerable<T> 线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5978726/