WPF:将项目添加到 ListView 的最有效/最快速的方法是什么? [英] WPF: what's the most efficient/fast way of adding items to a ListView?

查看:32
本文介绍了WPF:将项目添加到 ListView 的最有效/最快速的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在以相当高的频率添加的网格中显示大量行(在某些情况下每秒最多 10 行)我选择 ListView 是因为我认为它是 WPF 中最快的网格控件.(当然比GridView快很多)

I need to display lots of rows in a grid added at a pretty high frequency (up to 10 rows per second in some cases) I chose ListView because I assume is the fastest grid control in WPF. (certainly a lot faster than GridView)

在添加了几十万个项目后,CPU 利用率变得相当高,并且它们继续进来.这相当令人惊讶,因为 ListView 仅呈现可见行,因此总共添加了多少行应该无关紧要.

CPU utilization gets pretty high after couple hundred thousand items were added and they continue to come in. This is rather surprising, as ListView renders only the visible rows, so it should not matter how many are added in total.

我的第一种方法是将其绑定到 ObservableCollection,但过了一会儿,CPU 利用率上升,整个 Window 变得紧张.

My first approach was binding it to ObservableCollection but after a while, the CPU utilization goes up, and the whole Window get jittery.

我尝试将它绑定到一个常规列表,这似乎更快,但是我确实需要经常调用列表上的 .Refresh(),一段时间后它也会猛烈抨击 CPU.

Than i tried binding it to a regular List, which appears to be faster, however i do need to call the .Refresh() on the list often, which after a while slams the CPU as well.

比我尝试 将 ObservableCollection 子类化 到块插入希望批处理它们会提高性能/减少 cpu 工作量,但这种方法似乎需要调用 CollectionView.Refresh,这与在集合上调用 Reset() 相同,并且当集合中有很多项目时也效率低下.

Than i attempted subclassing ObservableCollection to chunk inserts hoping that batching them would improve performance/decrease cpu workload, but this approach appears to require calling CollectionView.Refresh which is the same as calling Reset() on the collection, and also ineficient when there are lots of items in the collection.

清除 observablecollection 并调用 myListView.Items.Refresh() 将其恢复为 0,从而使 CPU 使用率回到起点.

Clearing the observablecollection and than calling myListView.Items.Refresh() to bring it back down to 0 brings cpu usage back to the starting point.

这里开始没有想法了.. 同样,我在这里的目标是以最高效的方式添加/显示大量项目并显示 8 列网格.. ListView 看起来不错,只是必须有一些方法我可以进一步调整它..

Starting to run out of ideas here.. Again, my aim here, is to add/display lots of items and display 8 column grid, in the most performant manner.. ListView seems good, there just have to be some ways i could further tweak it..

更新

在分析之后,ObservableCollection 在网格中 800k 行,cpu 最密集的工作是由:

after profiling, ObservableCollection 800k rows in the grid, the most cpu intensive work is done by :

  • (75%) System.Windows.Media.MediaContext.RenderMessageHandler(object resizedCompositionTarget)
  • (20%) ObservableCollection.OnCollectionChanged(NotifyCoolectionChanged..)

尽管这些数字因会话而异..

although depending on session those numbers vary greatly..

更新 2 .. 好的 BindingList 显然是这里的赢家.

以下是并排结果(以刻度为单位),每行 100 万行(每秒添加 10 个项目):

here are results (in ticks) side by side with 1 million rows each (and adding 10 items per second):

可观察集合:http://i.imgur.com/7ZoSv.png

绑定列表http://i.imgur.com/jm5qF.png

您可以看到 CPU 活动总体下降,并且在绑定列表情况下处理树所需的滴答时间减少了大约一半!感谢 Akash 提出的这个好主意.

you can see overall drop in CPU activity, and about half the ticks required to process the tree in Binding List case! My thanks to Akash for this great idea.

推荐答案

我建议使用 BindingList 类,而不是使用 ObservableCollection,你可以这样做..

Instead of using ObservableCollection I will suggest BindingList class, you can do something like this..

BindingList<string> list = new BindingList<string>();

list.AllowEdit = true;
list.AllowNew = true;
list.AllowRemove = true;

// set the list as items source
itemCollection.ItemsSource = list;

// add many items...

// disable UI updation
list.RaiseListChangedEvents = false;

for each(string s in MyCollection){
   list.Add(s);
}

// after all.. update the UI with following
list.RaiseListChangedEvents = true;
list.ResetBindings(); // this forces update of entire list

您甚至可以批量启用/禁用更新,而不是一次性添加所有内容,BindingList 在我所有的 UI 中都比 ObservableCollection 运行得更好,我想知道为什么当 BindingList 真正取代 ObservableCollection 时,人们到处都在谈论 ObservableCollection.

You can enable/disable updating even in batches, instead of adding everything at one shot, BindingList has been functioning better then ObservableCollection in all my UI, I wonder why everywhere people talk more about ObservableCollection when BindingList really superseds ObservableCollection.

这篇关于WPF:将项目添加到 ListView 的最有效/最快速的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆