2015-04-03 92 views
-1

我有这样的代码,低于该执行的消息的ObservableCollection其收集通过以太网连接的ObservableCollection触发太多CollectionChanged

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; 
     } 
    } 
); 

BeginInvokeRxEventHandler

private void RxEventHandler(RxMessage msg) 
    { 
     UiDispatcher.BeginInvoke(_rxMsgUpdater, DispatcherPriority.Normal, msg); 
    } 

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> 

通过后台线程调用......

的UI是优秀和良好,只要后台线程正在呼叫RxEventHandler类似于每秒20次。 一旦我把真实的流量放进去,这个被称为每秒1000次的东西。

所以我通过扩展ObservableCollection试过的东西,我开始收集基本的ObservableCollectionOnCollectionChanged并触发每500毫秒CollectionChanged事件所改变的项目。 这显然扔RangeNotSupportedException,我不得不改用以下,

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左右时,则需要几秒钟。

我正在向数据网格馈送此数据,如上所示,我也启用了Virtualization。现在我做了大量的搜索,并且我还没有找到解决这个问题的人。 有人可以给我这个建议吗?

我已经做了一些分析和CPU猪是PresentationFramework.ni.dll,似乎涉及到众多CollectionChanged事件。 现在我有一些响应,但以限制收集计数为代价。这不是我想要做的。

+0

您正试图解决错误的问题。核心问题在于你设计了一个对人类完全无法使用的用户界面。没有人可以每秒阅读数千行文字,您显示的信息无用。创建一个可用的用户界面,例如,用户可以在闲暇时查看一段消息的冻结快照。 BeginInvoke()问题也自动解决。 – 2015-04-03 12:38:53

+0

是的,我同意,但是我正在处理一个处理总线(以太网,Flexray等)跟踪的应用程序。这意味着我需要在UI上加载这些消息,以便用户可以检查。因此,用户只需检查消息并过滤他感兴趣的消息,然后滚动并检查其他消息。所以更新必须在那里。我正在寻找的是实时更新和人类可用性的妥协。 – WinterS 2015-04-03 12:47:09

回答

2

由于此问题的性质,您应该使用某种类型的处理队列,然后创建一个分离处理处理程序的处理程序。此外,由于您使用的数据量很大,因此您应该使用计时器以每x秒/分钟的速度查询新更新并以此方式刷新数据网格,或者您应该使用某种类型的虚拟化面板来处理数量庞大的数据被传递到它(的ListView/GridView控件)

相关问题