INotifyCollectionChanged - 它多久发射一次(以及它们如何使它如此高效/快速)?

时间:2011-10-03 14:58:57

标签: c# wpf performance observablecollection inotifycollectionchanged

基本上,我想知道它在这里的效率如何。

示例代码:

void GetItems()
{
    foreach (var item in items)
        myObservableCollection.Add(item);
}

每次导致UI必须每次刷新时,是否会触发CollectionChanged事件?或者它是否这样做以便等待GetItems函数完成?

基本上,似乎WPF处理得很好,我想知道他们是如何做到的。

3 个答案:

答案 0 :(得分:4)

Optimizing Performance: Data Binding提供了有关如何解决数据绑定的一些背景知识,包括不同项目来源的性能影响。请查看Binding to an ItemsSource部分。

  

考虑一个拥有CLR List对象的场景   要在ListBox中显示的员工列表。创建一个   这两个对象之间的对应关系,你会绑定你的员工   列表到ListBox的ItemsSource属性。但是,假设你   让一名新员工加入您的团队。你可能会认为这是有序的   要将此新人插入到绑定的ListBox值中,您可以   只需将此人添加到您的员工列表中,并期望进行此更改   被数据绑定引擎自动识别。

     

这种假设将被证明是错误的;实际上,改变不会   自动反映在ListBox中。这是因为CLR   List对象不会自动引发更改的集合   事件。为了让ListBox获取更改,您可以   必须重新创建您的员工列表并将其重新附加到   ListBox的ItemsSource属性。虽然这个解决方案有效,但它   引入了巨大的性能影响。每次你重新分配   ListBox的ItemsSource到一个新对象,ListBox首先抛弃   它以前的项目并重新生成其整个列表。表现   如果ListBox映射到复杂的DataTemplate,则会放大影响。

     

解决此问题的一个非常有效的方法是让您的员工   列出一个ObservableCollection。一个ObservableCollection对象   引发数据绑定引擎可以发生的更改通知   接收。该事件从ItemsControl添加或删除项目   无需重新生成整个列表。

     

更新1个项目的时间(毫秒)

     
      
  • 到CLR列表对象= 1656毫秒
  •   
  • 至ObservableCollection = 20 ms
  •   

WPF永远不会直接绑定到集合。如果将集合指定为绑定源,则WPF实际上绑定到集合的default view

  

集合视图是绑定源集合顶部的图层   允许您基于导航和显示源集合   排序,过滤和分组查询,而无需更改   底层源集合本身。集合视图也可以维护   指向集合中当前项的指针。如果来源   collection实现了INotifyCollectionChanged接口   CollectionChanged事件引发的更改将传播到   视图。

答案 1 :(得分:3)

每次更改都会触发事件。

GUI不必每次都做出反应和刷新,它可以推迟 我知道WinForms会对此进行优化,我认为WPF也有类似的方法。

答案 2 :(得分:0)

如果您想查看UI请求新结果的频率,请将其公开为公共属性,并将调试行放在myObservableCollection的公共属性的get(评估者)中。