将列表合并到ObservableCollection中会抛出太多的属性更改通知

本文关键字:太多 属性 通知 合并 列表 ObservableCollection | 更新日期: 2023-09-27 17:53:51

我正在c# . net中开发一个小型独立系统,运行在嵌入式处理器上,我们使用GTK作为UI并将数据存储在MySql数据库中。数据库访问是通过我们自己的数据访问层完成的,我们使用我们自己的转换层将Model类型转换为DAO类型。

为了访问系统中的数据,我们为每种类型都有一个数据存储类,这个类保存所有活动项的索引列表(只有名称和ID,我们做延迟加载),这目前包含在UI绑定的ObservableCollection中。

当我们更新这个列表时,我们从DB读取索引,将项目从DaoTypes转换为Model类型,然后将它们输入到ObservableCollection中。

负责UI的家伙刚刚提出了一个Jira票据,说以这种方式添加到ObservableCollection会为我们输入的每个项目引发一个Notify Property Changed事件,这使得它无法用于他的UI。

我不确定这是否与我使用ObservableCollection做事的方式有关,或者如果UI应该能够处理这种级别的负载,我们不是在谈论项目的负载,可能最多20-50个。

我试着在飞行中维护这个列表,手动添加和删除项目,而不是每次加载列表,但加载列表新鲜更可靠。

    我们应该能够期望UI可以处理这些属性更改通知吗?
  • 是否有比这样使用ObservableCollection更有效的方法?

将列表合并到ObservableCollection中会抛出太多的属性更改通知

如果没有更多的细节,或者没有一个好的,最小的完整的代码示例来清楚地说明问题,就不可能有任何真正的信心提供建议。

说:

我们应该能够期望UI可以处理这些属性更改通知吗?

这取决于UI和平台。对于台式计算机,在UI对象中插入50次是微不足道的。对于嵌入式平台,这可能是一个问题。这可能是灾难性的UI编写幼稚,并针对电子纸显示(即具有令人痛苦的刷新率缓慢的显示)。

请注意,如果你想把这个问题推到UI代码,界面是由于某种原因无法处理50个单独的更新,它可以保持一个计时器和更新UI集合被修改后只有当没有修改发生在一段时间内(例如100 ms…或任何延迟将是适当的在你的场景中,例如依赖无论你使用框架的延迟,延迟自己的代码,等等)。

是否有比这样使用ObservableCollection更有效的方法?

ObservableCollection<T>的全部意义在于,当集合发生更改时,可以通知集合的消费者。这在WPF场景中很常见且非常有用。没有办法禁用此行为。

请注意,如果您不必绑定到ObservableCollection<T>本身,您可以使用BindingList<T>类代替。它有一个RaiseListChangedEvents属性,您可以将其设置为false来禁用通知。

但是即使ObservableCollection<T>有这样的功能,或者你能够切换到BindingList<T>,那么你会有一个不同的问题:如何向UI发出信号,你已经完成了向列表添加元素。既然你必须解决这个问题,你就可以实现它,并使用任何集合类型(因为这样的机制应该适用于任何集合类型)。

UI绑定到ObservableCollection

你使用的是什么绑定实现?内建在。net中的东西?如果有,是哪一个?别的吗?

请注意,任何。net绑定实现都可以正确处理整个集合被另一个集合替换的场景,无论是通过直接为集合设置UI属性,还是UI属性本身绑定到可绑定属性(例如由XXXChanged, INotifyPropertyChanged支持,或者在WPF或Winrt中是实际的DependencyProperty)。

换句话说,如果您正在使用具有"合理"行为的绑定实现,那么只需填充整个新列表并将绑定集合重置为新列表的建议应该可以正常工作。当UI看到集合对象的引用值发生变化时,它可以根据新的集合对象相应地重建UI。


我要指出的是,由于您似乎认识到在重新加载新集合方面的可靠性价值,而不是在编辑发生时维护单个集合,我认为您也会同样认识到在UI代码方面这样做的价值。

。即使没有性能问题,如果你要基于DB内容自己重建列表,难道给UI一个全新的集合不是很有意义吗?这当然更容易,并且在插入和删除发生时通过更新UI可能获得的任何理论上的性能增益都被您的层所损失,这显然将此类编辑分组为单个大规模更新操作。