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# - Linq:将 IEnumerable<Point> 转换为 IEnumerable<float>

c# - 我需要在处理完控件后删除控件吗?

c# - 给定排序字符串的游程编码

c# - Animate 如何改变 wpf 中的 ColumnDefinition 宽度?

c - 在 C 语言中,为什么只在初始化已创建线程列表后才调用 pthread_join?

C#:更新 List<of T> 中的项目值

c# - 如果没有订阅者在一个月内不检索消息,如何自动删除 Azure 服务总线中的队列?

C++ 错误类型 'std::thread' 无法解析 Eclipse Mars 4.5,Ubuntu 12.04

java - 将 ThreadLocal 类传递给另一个线程?

c# - 区分和排序列表 LINQ