ReadOnlyCollection(of T)的文档指出:



我的问题涉及粗体部分:

  • 为什么通过集合进行枚举本质上不是线程安全的
  • 可能有什么含义,以及
  • 常用的解决方法是什么?
  • 最佳答案

    C#有一个很好的集合模型,但是ReadOnlyCollection类是整个模型中最不幸的(或命名的)类之一。应该将它更恰本地称为只读列表,而不是只读集合。

    现在,要解决您的问题,它只是在构造时提供的IList的只读装饰器。因此,构造ReadOnlyCollection的代码可能会修改原始列表,从而给多线程访问带来所有后果。

    因此,如果集合真正是只读的,则枚举整个集合将是线程安全的。但是由于它不是只读的,所以不是线程安全的。考虑到您拥有的声誉,我很确定您不会怀疑为什么通过非只读集合枚举不是线程安全的。

    至于您所要求的解决方法,可以使用锁定,也可以不使用锁定(或尽可能小的锁定)原理,并制作列表的真实只读副本。

    编辑

    几个月后,我在重新阅读我的答案(感谢asyncwait的评论),我意识到我应该已经回答了OP的所有问题,而无需根据他的声誉做出假设。 OP可能已经收到了他的答复,但是为了将来的读者,我会这样做。

    出于同样的原因,通过非真正只读的集合进行枚举本质上也不是线程安全的,因为即使在单线程方案中,枚举时也无法修改集合。 (在Java中为ConcurrentModificationException,在C#中为InvalidOperationException。)在单线程方案中,您可以确保枚举代码不会尝试以任何方式更改集合,但是在多线程方案中,一个线程可能正在枚举集合,而另一个线程可能会同时对其进行更改。

    10-07 20:01
    查看更多