2015-04-03 89 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控件)

相關問題