首页 > 解决方案 > 如何使 ENumerable 操作踏上安全的 SynchronizedCollection?

问题描述

当我使用SynchronizedCollection时,我可以捕获异常

System.InvalidOperationException
Collection was modified; enumeration operation may not execute.

foreach循环中。

如果你看一下 SynchronizedCollection 类的源代码,即 GetEnumerator 方法(其中有两个实际上一个是显式接口实现),你会看到:

List<T> items;

IEnumerator IEnumerable.GetEnumerator()
{
    return ((IList)this.items).GetEnumerator();
}

public IEnumerator<T> GetEnumerator()
{
    lock (this.sync)
    {
        return this.items.GetEnumerator();
    }
}

它返回不是线程安全的内部列表的枚举器

编辑。我问的不是在并发情况下我能做什么。我在问

如何使其线程安全?

标签: c#listasynchronousconcurrencysynchronization

解决方案


我认为有两种解决方案:

  1. 在 System.Collections.Concurrent 命名空间中使用ConcurrentBag<T>或其他集合。(注意 ConcurrentBag 中的元素不会被排序。)
  2. 检索数据时创建快照。

在性能成本方面,第二个更安全。

如果您使用的是 .NetCore,ImmutableList<T>是一种更好的快照方式,并且可以避免浅拷贝问题。


推荐阅读