触发的ObservableCollection太多CollectionChanged [英] ObservableCollection triggering too many CollectionChanged
问题描述
我有这样的代码,低于该执行 的ObservableCollection
这是收集通过以太网连接的邮件
I have this code below which perform async update of an ObservableCollection
of Messages which are collected over an Ethernet Connection
的ObservableCollection
ObservableCollection
private readonly ObservableCollection<MsgDisplayViewModel> _rxGridMessages;
public ObservableCollection<MsgDisplayViewModel> RxGridMessages
{
get { return _rxGridMessages; }
}
动作
Action
_rxMsgUpdater = new Action<RxMessage>((RxMessage msg) =>
{
if (_rxGridMessages.Count < 2000)
{
_rxGridMessages.Add(new MsgDisplayViewModel(msg, DataCollection.DataBase));
}
else
{
var dispmsg = new MsgDisplayViewModel(msg, DataCollection.DataBase);
_rxGridMessages[index++ % _rxGridMessages.Count] = dispmsg;
}
}
);
的BeginInvoke
通过后台线程从名为 RxEventHandler
BeginInvoke
called by Background thread from RxEventHandler
private void RxEventHandler(RxMessage msg)
{
UiDispatcher.BeginInvoke(_rxMsgUpdater, DispatcherPriority.Normal, msg);
}
XAML
XAML
<DataGrid Name="TraceGrid"
ItemsSource="{Binding MyVm.RxGridMessages, Mode=OneWay, IsAsync=True}"
SelectionMode="Single" AutoGenerateColumns="False" VirtualizingPanel.IsVirtualizing="True" FontSize="10"
HorizontalAlignment="Stretch" IsReadOnly="True" RowDetailsVisibilityMode="Visible" BorderBrush="{DynamicResource AccentColorBrush}" BorderThickness="1" EnableColumnVirtualization="True"
EnableRowVirtualization="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.IsDeferredScrollingEnabled="True"
>
<DataGrid.Columns>
...
...
用户界面是细而只要后台线程正在调用好 RxEventHandler
像每秒20次。
有一次,我在把真实流量,在 RxEventHandler
被称为像每秒1000次。
The UI is fine and good as long as the background thread is calling the RxEventHandler
something like 20 times per second.
Once I put the real traffic in, the RxEventHandler
is called something like 1000 times per second.
所以,我想的东西通过延长 的ObservableCollection
后,我开始收集的基础上,改变项目的 OnCollectionChanged
的ObservableCollection
并每隔500毫秒触发> CollectionChanged
事件。
显然,它扔 RangeNotSupportedException
,我不得不使用下面的代替,
So I tried something by extending the ObservableCollection
, I started collecting the changed items on the base OnCollectionChanged
of ObservableCollection
and trigger every 500 ms a CollectionChanged
event.
It obviously threw RangeNotSupportedException
and I had to use the following instead,
try
{
base.OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Add, addedItems, itemaddedindex));
}
catch (System.NotSupportedException)
{
base.OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Reset));
}
的问题是,集合为重建且有一定的延迟它得到前显示。如果集合项目计数低这是相当快。但是,当它是1000左右,那么它需要几秒钟。
The problem is that the collection is rebuild and there is some delay before it gets displayed. If Collection item count is low it is pretty quick. But when it is 1000 or so then it takes some seconds.
我喂这个到DataGrid如上图所示,我已经启用的 虚拟化
为好。现在,我已经做了很多的google搜索,我还没有发现有人用变通针对此问题。
谁能指点我一下吗?
I am feeding this to the datagrid as shown above and I have enabled Virtualization
as well. Now I have done a lot of googling and I have not found someone with a work around for this problem.
Can anybody advice me on this?
我做了一些分析和CPU的猪是的 PresentationFramework.ni.dll
它似乎涉及到众多的 CollectionChanged
事件。
现在我有反应,但在限制集数的成本的东西。这不是我想做的事。
I have done some profiling and the CPU hog is PresentationFramework.ni.dll
and it seems related to the numerous CollectionChanged
events.
Right now I have something responsive but at the cost of limiting the Collection count. This is not what I wanted to do.
推荐答案
在Visual Studio中新2015年
new in Visual Studio 2015
BulkObservableCollection
的 https://msdn.microsoft.com/en-us/library/dd867973.aspx
这篇关于触发的ObservableCollection太多CollectionChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!