Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF:what';将项目添加到ListView的最有效/最快速的方法是什么?_Wpf_Performance - Fatal编程技术网

WPF:what';将项目添加到ListView的最有效/最快速的方法是什么?

WPF:what';将项目添加到ListView的最有效/最快速的方法是什么?,wpf,performance,Wpf,Performance,我需要在一个网格中以相当高的频率显示大量的行(在某些情况下高达每秒10行) 我选择ListView是因为我认为它是WPF中最快的网格控件。(当然比GridView快得多) 在添加了几十万个项目之后,CPU的利用率变得相当高,而且这些项目还在不断增加。这是相当令人惊讶的,因为ListView只呈现可见的行,所以不管总共添加了多少行 我的第一种方法是将它绑定到ObservaleCollection,但过了一段时间,CPU利用率上升,整个窗口变得不稳定 然后我尝试将它绑定到一个常规列表,这似乎更快,但

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

在添加了几十万个项目之后,CPU的利用率变得相当高,而且这些项目还在不断增加。这是相当令人惊讶的,因为ListView只呈现可见的行,所以不管总共添加了多少行

我的第一种方法是将它绑定到ObservaleCollection,但过了一段时间,CPU利用率上升,整个窗口变得不稳定

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

然后,我尝试对插入块进行分块,希望对它们进行批处理可以提高性能/减少cpu工作负载,但这种方法似乎需要调用CollectionView.Refresh,这与调用集合上的Reset()相同,并且在集合中有很多项时也没有用

清除ObservaleCollection并调用myListView.Items.Refresh()将其恢复为0会将cpu使用率恢复到起点

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

更新

在对网格中的800k行进行评测后,cpu密集度最高的工作由以下人员完成:

  • (75%)System.Windows.Media.MediaContext.RenderMessageHandler(对象大小调整的CompositionTarget)
  • (20%)可观察到的集合。OnCollectionChanged(NotifyCoolectionChanged…)
尽管这些数字因会话而异,但差别很大

更新2。。ok BindingList显然是这里的赢家。

以下是以100万行(每秒添加10项)并排显示的结果(以记号表示):

可观察收集:

绑定列表


您可以看到CPU活动的总体下降,以及在绑定列表情况下处理树所需的大约一半时间!我感谢阿卡什提出了这个好主意

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

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=newbindingList();
list.AllowEdit=true;
list.AllowNew=true;
list.AllowRemove=true;
//将列表设置为源项
itemCollection.ItemsSource=列表;
//添加许多项目。。。
//禁用UI更新
list.RaiseListChangedEvents=false;
对于每个(MyCollection中的字符串s){
列表。添加(s);
}
//毕竟。。使用以下命令更新UI
list.RaiseListChangedEvents=true;
list.ResetBindings();//这将强制更新整个列表

您甚至可以成批启用/禁用更新,而不是一次性添加所有内容,BindingList在我的所有UI中都比ObservableCollection运行得更好,我想知道为什么在BindingList真正超越ObservableCollection的情况下,到处都有人谈论ObservableCollection。

Akash,谢谢。我将很快测试此集合。我很好奇的一件事是,是否有一种方法可以批量插入并刷新整个列表。我相信当800k项目被刷新时,这会导致很多抖动和cpu工作。我不认为它会刷新800k项目,因为虚拟化面板只会刷新屏幕上的有限项目。然而,另一种方法是使用某种寻呼机来分页您的项目,在我的应用程序中,我只首先加载0-20,然后让用户逐个导航其余的项目,他们也可以使用某种搜索进行过滤您尝试过过滤您的绑定列表吗?对于ObservableCollection,我使用的是CollectionViewSource,因为它提供了一个过滤器,过滤器在每个添加的项上执行。该过滤器可能在刷新后对所有行执行。所以我需要找到另一种方法来添加筛选。抱歉,我猜筛选是不可能的,但您可以尝试筛选UI,ItemsCollection of ItemsControl确实允许筛选,您还可以在加载时从模型中筛选数据,然后将其传递给控件。您还可以创建自己版本的绑定列表,您必须使一个类派生或包含任何列表,并实现IBindingList接口!!为了出色的表现。