问题描述
我在wpf应用程序中使用OxyPlot作为行记录器。就像LiveDemo的例子。 在较大的可见数据集上,我遇到一些UI性能问题,并且可能整个应用程序可能冻结。似乎是PlotModel.InvalidatePlot,它经常被调用很多点,但是我没有找到更好的方法。
深处:
- 使用OxyPlot 2.0.0
- 我在PlotModel中全部编码。 Xaml PlotView仅绑定到PlotModel。
- 我周期性地在线程中收集数据,然后将其放入DataSource(LineList的ItemSoure的List列表)
- 我有一个在线程中计算x和y轴表示形式的循环的类。完成所有这些操作后,它将调用PlotModel.InvalidatePlot。
如果我
- 在显示器上有超过100 k点(无论是否在多个Lineseries中)
- 并每500毫秒为每个Lineseries添加1个DataPoint
- 并每200毫秒调用PlotModel.InvalidatePlot
不仅PlotView出现性能问题,而且即使我调用PlotModel.InvalidatePlot(false),窗口的响应也非常慢。
我的目标
我的目标是使Windo /应用程序正常运行。它不应因线路记录器而挂断。最好的办法是没有性能问题,但我对此表示怀疑。
我发现或测试过的东西
OxyPlot具有Performance guidelines。我正在使用带DataPoints的ItemsSource。我也尝试过将它们直接添加到Lineseris.Points中,但是Plot无论如何都不会刷新(即使使用ObservableCollection也是如此),因此我必须调用PlotModel.InvalidatePlot,其结果相同。我无法绑定到Xaml中定义的Lineseries,因为我不知道会有多少行。也许我错过了直接添加积分的事情?
我还发现了一个Github问题1286,它描述了一个相关问题,但是这种解决方法在我的测试中速度较慢。
我还检查了调用PlotModel.InvalidatePlot所花费的时间,但是点数不影响它。
我已经检查了UI线程,似乎很难处理大量的点
如果我放大绘图并在20 k点以下显示,那么
问题:
除了调用PlotModel.InvalidatePlot少得多之外,还有其他方法可以更好地处理此问题吗?
限制:
我还必须更新轴和注释。所以,我想我不会再打电话给PlotModel.InvalidatePlot。
解决方法
到目前为止,我最终计算了下次调用InvalidatePlot的时间。我使用此answer中给出的方法进行计算,返回可见点的数量。这样可以减少性能问题,但是可以在调用InvalidatePlot时修复UI线程上的块。
,我发现使用 OxyPlot Windows 窗体实现,然后使用 WPF 中的 Windows 窗体集成显示它可以提供更好的性能。
例如
var plotView = new OxyPlot.WindowsForms.PlotView();
plotView.Model = Plot;
var host = new System.Windows.Forms.Integration.WindowsFormsHost();
host.Child = plotView;
PlotContainer = host;
其中“Plot”是您调用 InvalidatePlot() 的 PlotModel。
然后在您的 XAML 中:
<ContentControl Content="{Binding PlotContainer}"/>
或者您想以其他方式使用 WindowsFormsHost。