.net - .NET ObservableCollection<> ToList() 线程安全吗?如果没有,如何进行

标签 .net thread-safety observablecollection

我有一个 ObservableCollection 的日志,我通过一个属性绑定(bind)到我的 GUI

public ObservableCollection<ILog> Logs {get; private set;}

需要在其他地方显示日志的子集,所以我有:
public ObservableCollection<ILog> LogsForDisplay
    {
        get
        {
            ObservableCollection<ILog> displayLogs = new ObservableCollection<ILog>();
            foreach (Log log in Logs.ToList()) // notice the ToList()
            {
                if (log.Date != DateTime.Now.Day)
                    continue;
                displayLogs.Add(log);
            }
            return displayLogs;

        }

在我添加“ToList()”之前,我偶尔会遇到关于“集合已修改;枚举操作可能无法执行”的异常。这是有道理的——当我迭代它时,有人可以添加到日志中。我从 Collection was modified; enumeration operation may not execute 得到了“ToList”的想法这似乎表明 ToList 是要走的路,并暗示它是线程安全的。但是 ToList() 线程安全吗?我假设在内部它必须使用列表并对其进行迭代?如果有人同时添加到该列表中怎么办?仅仅因为我没有看到问题并不意味着没有问题。

我的问题。
ToList() 线程是否安全,如果不是,保护日志的最佳模式是什么?如果 ToList() 是线程安全的,你有引用吗?


奖金问题。如果要求发生变化并且我需要在 GUI 上显示的只是 LogsForDisplay 而不是 Logs,我可以将 Logs 更改为可以解决问题的其他内容吗?比如 ImmutableList ?然后我不必调用 ToList<> ,我认为这需要一些时间来制作副本。

让我知道我是否可以提供澄清。
谢谢,

戴夫

最佳答案

ToList的执行扩展方法归结为通过 Array.Copy 将项目从一个数组复制到另一个数组。方法,其中隐藏 Collection was modified您的错误不是线程安全的,当在 Array.Copy 期间更改基础项目时,您可能会遇到奇怪的行为调用。

我建议它使用CollectionView对于绑定(bind),我在类似的情况下使用了很长时间,到目前为止没有遇到任何问题。

// somewhere in .ctor or other init-code
var logsForDisplay = new CollectionView(this.Logs);
logsForDisplay.Predicate = log => ((Log)log).Date == DateTime.Now.Day;

public CollectionView LogsForDisplay { get { return this.logsForDisplay; } }

你可以有另一个CollectionView对于不同的用例,例如:
// somewhere in .ctor or other init-code
var yesterdaysLogs = new CollectionView(this.Logs);
yesterdaysLogs.Predicate = log => ((Log)log).Date == DateTime.Now.AddDays(-1).Day;

public CollectionView YesterdaysLogs{ get { return this.yesterdaysLogs; } }

关于.net - .NET ObservableCollection<> ToList() 线程安全吗?如果没有,如何进行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42863249/

相关文章:

c# - 请求线程在不强制退出的情况下退出?

c# - 我如何根据每个元素的条件循环可观察序列?

c# - 具有 ObservableCollection 和 INotifyPropertyChange 的 Json.Net 类层次结构被序列化但未反序列化

c# - 如何使用 Linq 和 XML 实现通用方法方法

c# - 如何在 .NET 中导入使用 sn.exe 生成的 .snk 文件?

multithreading - 将发送特征添加到装箱特征对象时的奇怪行为

c# - ObservableCollection CollectionChanged 事件未引发

c# - 作为配置属性的不可变类型

c# - 依赖注入(inject) wcf

java - 在多线程应用程序中使用带有 volatile 原语的条件运算符是否安全