ste*_*g89 18 c# wpf performance observablecollection
我有一个设置,可能会有成千上万的项目(想想3000-5000)被添加到ObservableCollection
绑定到某个可视界面的项目中.目前,添加它们的过程非常缓慢(大约4秒/ 1000项),当然GUI在此期间没有响应.处理将多个项目一次移动到集合中而不用担心系统锁定的好方法是什么?我看过了,DispatcherTimer
但我不确定它是否会提供我需要的一切.
另一个问题 - 我是否可以采取一些措施来加速这些对象的创建,以便将它们添加到集合中并不需要很长时间?目前我使用它们是这样的:Collection.Add(new Item(<params>))
事先在后台线程中生成项目会减少将它们添加到显着数量所需的时间吗?
编辑:虚拟化是不可能的.要求指定WrapPanel
外观,因此显示实际上是ListBox
具有模板化ItemsPanel的显示
编辑2:根据秒表,瓶颈实际上是把物品放进我的ObservableCollection
.我将尝试更改该集合类型并进行自己的通知,看看是否会大大加快它的速度.
编辑3:所以答案是在一个地方 - 我通过创建一个继承自的类来解决这个问题(在下面的帮助下)ObservableCollection
.这个类做了两件事 - 公开一次添加集合的方法,并添加了抑制CollectionChanged
事件的能力.通过这些更改,添加3000个项目所需的时间大约为.4秒(97%的改进).此链接详细说明了这些更改的实现.
Binding
由于这个原因,WPF 支持并发.尝试设置Binding.IsAsync
为true.此外.
ObservableCollection<T>
,这样做很慢,因为每次添加一个项目都会引发事件.使用更快的东西,List<T>
并在添加所有项目后提出属性更改通知.你说1000,所以我会坚持这个数字.
IIRC,可观察的集合有一个小缺点 - 如果你逐个添加项目,它会提高每个项目一次通知.这意味着您有1000个项目的1000个通知,并且UI线程将以致命的速度运行,以便跟上重新绘制屏幕的步伐.
你需要尽快重绘吗?也许你可以批量添加?将1000件物品分成几件100件装,或多件50件或20件装.然后,不要将所有项目逐个放入,而是将它们放入数据包中.但要注意:你必须使用像自己的集合实现的AddRange之类的方法,而不是LINQ,否则你将再次逐个插入.如果找到这样的方法,它应该显着减少事件的数量,因为每次AddRange调用时集合应该只引发一次Changed事件.
如果可观察集合没有AddRange,要么使用不同的集合,要么编写自己的集合,只需一个包装器即可.我们的目标是不在每一个Add()中引发Changed事件,但是在合理计算它们之后,或者 - 也许只是跳过提高在添加项目时更改并在某些固定时间间隔内提高更改?如果您的数据以恒定速率无限期地"流入",这将特别有益.
当然,在屏幕上显示的那些项目中,您也可以自己进行渲染.如果您的ItemTemplates很复杂,1000个对象乘以1000个可视图层/属性实例可能会破坏用户体验.您是否已将ItemTemplates简化为最低限度?
最后一点:考虑使用StackPanels虚拟化作为ItemsControl/ListBoxes中的ItemPanels.它可以大大减少内存占用量和单个时间点绘制的项目数量.这不一定有助于提出的数量或事件,但是当您拥有复杂的项目模板时,它可能会有很大帮助!
编辑:您正在使用ObservableCollection,所以我假设WPF/Silverlight ..如果这不正确则更新问题
归档时间: |
|
查看次数: |
12365 次 |
最近记录: |