ReadOnlyCollection(of T)的文档指出:
我的问题涉及粗体部分:
最佳答案
C#有一个很好的集合模型,但是ReadOnlyCollection类是整个模型中最不幸的(或命名的)类之一。应该将它更恰本地称为只读列表,而不是只读集合。
现在,要解决您的问题,它只是在构造时提供的IList的只读装饰器。因此,构造ReadOnlyCollection的代码可能会修改原始列表,从而给多线程访问带来所有后果。
因此,如果集合真正是只读的,则枚举整个集合将是线程安全的。但是由于它不是只读的,所以不是线程安全的。考虑到您拥有的声誉,我很确定您不会怀疑为什么通过非只读集合枚举不是线程安全的。
至于您所要求的解决方法,可以使用锁定,也可以不使用锁定(或尽可能小的锁定)原理,并制作列表的真实只读副本。
编辑
几个月后,我在重新阅读我的答案(感谢asyncwait的评论),我意识到我应该已经回答了OP的所有问题,而无需根据他的声誉做出假设。 OP可能已经收到了他的答复,但是为了将来的读者,我会这样做。
出于同样的原因,通过非真正只读的集合进行枚举本质上也不是线程安全的,因为即使在单线程方案中,枚举时也无法修改集合。 (在Java中为ConcurrentModificationException,在C#中为InvalidOperationException。)在单线程方案中,您可以确保枚举代码不会尝试以任何方式更改集合,但是在多线程方案中,一个线程可能正在枚举集合,而另一个线程可能会同时对其进行更改。