c# - 线程和 IEnumerable; "Collection Was Modified"- 异常

标签 c# multithreading linq

假设在下面的类中,一个线程获取 IEnumerable 对象并开始对元素进行迭代。在迭代过程中,另一个线程出现并通过 Add 方法向 library_entries 添加一个新条目。会在迭代中抛出“集合已修改”异常吗?或者在迭代完成之前锁会阻止添加元素吗?还是两者都不是?

谢谢!

public static class Library
{
    private static List<string> library_entries = new List<string>(1000000);

    public static void Add(string entry)
    {
        lock (library_entries)
            library_entries.Add(entry);
    }

    public static IEnumerable<string> GetEntries()
    {
        return library_entries.Where(entry => !string.IsNullOrEmpty(entry));
    }
}

最佳答案

不,您不会得到异常,您使用的是 Linq 查询。更糟糕的是,它会出乎意料地失败。最典型的结果是相同的项目被枚举两次,尽管在 Add() 调用期间 List 重新分配其内部存储时任何事情都是可能的,包括 IndexOutOfRangeException。每周一次,给予或接受。

调用 GetEntries() 并使用枚举器的代码也必须获取锁。锁定 Where() 表达式还不够好。除非您创建列表的副本。

关于c# - 线程和 IEnumerable; "Collection Was Modified"- 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6726811/

相关文章:

c# - 只读变量线程安全吗?

c - Linux 下的 TCP 客户端/服务器

c# - 使 Math.Log 在 Entity Framework 查询中工作

LINQ:使用 IEnumerable.Count() 或 IList.Count 以获得更好的性能

c# - 接收以固定时钟速率发送的 UDP 数据包流

c# - Excel 文件生成器 : How to test resulting file

c# - Linq-to-xml 按没有子元素的元素分组

c# - 当将 T 与 null 进行比较并且 T 是一个结构时,CLR 会做什么?

C++ 简单消费者生产者问题

c# - 在 Entity Framework 中创建动态 linq 排序和搜索顺序语句时