2

我正在创建具有一些简单嗅探器功能并显示用户转储数据包的应用程序。从转储文件中读取数据包,该文件会根据当前流量实时更新,然后将捕获的数据包添加到 Datagrid(每个数据包都是新行)。我使用数据绑定从实现 ICollectionChanged 接口的转储读取器获取数据包,因此 Datagrid 在每个新数据包上都会收到通知。Datagrid 使用虚拟化和延迟滚动。几乎一切正常 - 唯一的例外是巨大的 CPU 消耗。这种 CPU 使用率是由于我读取所有新数据包(每秒数千个)、格式化它们以供显示和每个数据包上升 CollectionChanged 事件,这会更新 Datagrid。对软件的要求是用户不必实时查看所有新数据包——它们每秒出现数十万个,所以没有人会注意到他们。用户只能查看某些数据包,当他想要时,他可以向下/向上滚动条到适当的位置以查看他想要的数据包,并且只有在这种情况下必须从文件中读取数据包。

问题是我希望Datagrid每秒更新一次以显示新数据包到达,最好通过将滚动条缩放到实际数据包数量,但不需要连续读取它们,格式化并调用CollectionChanged,因为它需要CPU时间,此外如果他不滚动条,用户将看不到新数据包。我被告知到达的数据包数量,因此我知道所有数据包的数量。

我试图添加假数据包(从而避免读取和格式化每个新数据包)只是为了强制 Datagrid 扩展到实际数据包计数。它几乎起作用了,因为 CPU 使用率下降并且当我滚动条时数据包只读。但是过了一会儿,当新的数据包被添加到Datagrid时,当前视图中的行开始随机重复,即在第一时刻视图中的数据包显示第1、第2、第3、第4、第5、第6等等,但是过了一会儿它们分别显示为第 1、第 2、第 3 和第 1、第 2、第 3。

我还尝试刷新绑定 - 它有效,但消耗的资源比第一种方法更多,所以我放弃了它。我还尝试刷新 Datagrid 的 listcollectionview - 与刷新绑定的效果相同。

接下来是当我想在一次调用 CollectionChanged 时添加数据包列表

NotifyCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, list));

我收到了 PresentationFramework.dll!System.Windows.Data.ListCollectionView.ValidateCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 引发的 Range 操作不受支持的错误

所以我不得不为数据包列表中的每个数据包调用 CollectionChanged,这也增加了 CPU 使用率。

综上所述,我想通知 Datagrid 有新的数据包/行,因此 Datagrid 滚动条将缩放到数据包的总数,但只有当用户滚动条时才会从文件中读取数据包。

对于如何解决我的问题的每一个建议,我都会非常感谢。

我刚刚意识到,有一件重要的事情要提,很抱歉我一开始就忘了说。我的 ObservableCollection 支持某种数据虚拟化,在内存中我只保存一些必要的数据包。当新数据包到达时,我只通知我的集合新数据包的数量,我不必调用集合的 Add 方法,因为我实际上没有向它添加任何数据包 - 所以实际上没有数据包被读取. Collection 包含关于那一刻数据包总数的信息,并且只有少量实际保存在内存中,以便网格可以显示它们。仅在必要时动态读取数据包,当它们不显示时,它们被释放。但是要通知网格有关新数据包的信息,我必须(我不知道如何做另一种更好的方法)调用 CollectionChanged 并且在此调用的参数中我需要提供每个新数据包。而这个对 CollectionChanged 的​​调用使得数据包被实际读取,这会消耗 CPU。我想重新调整网格,以便滚动条大小通知新数据包到达,但无需读取数据包并在每个新数据包调用 CollectionChanged (每秒可能发生数千次). 我希望仅在滚动条位置发生变化时读取数据包,因此处理每个数据包的昂贵操作将仅针对少数当前可见的数据包完成,而不是针对每个数据包。

4

1 回答 1

0

如果您的 DataGrid 绑定到 ObservableCollection。每个 T 包含有关给定数据包的信息,诀窍是使“T”类实例化非常快。

现在听起来您正在创建每个 T 并在将它们添加到集合时计算显示所需的所有信息。

它应该只在其构造函数中接收足够的信息,以便稍后当用户滚动网格以查看其行时,它可以检索有关数据包的信息。

于 2012-11-28T22:12:55.713 回答