我们有几个图表显示来自表面 EMG 传感器的过滤数据。此数据通过 TCP 接收并使用事件传播。数据包属于 DataPackets 类型,因此会被过滤掉。我正在使用缓冲区让数据包以 30FPS 的速度通过。我正在使用 Reactive Extensions 收听此事件,如下所示:
Observable.FromEvent<Packet>(h => this.DataService.PacketReceived += h, h=> this.DataService.PacketReceived -= h)
.OfType<DataPacket>()
.Buffer(TimeSpan.FromSeconds(1.0 / 30))
.ObserveOnDispatcher()
.Subscribe(
packet => this.ReceiveDataPackets(packet.ToList()),
err => this.Log.Error("Error subscribing to data packets", err),
() => this.Log.Info("Finished listening to data packets"));
为了显示 EMG 数据,我们使用 Telerik ChartView。我遇到的问题是数据更新不流畅,图表不稳定。
这可能有几个原因:
- Telerik 图表对于每秒 1000 个数据点来说不够快
- DispatcherTimer 不会以恒定速率触发
- 数据不是以恒定速率接收的
点 1 是通过对输入数据进行采样来解决的,因此图中只有 1000 个点可见。
不幸的是,第2点无法解决。我尝试将优先级提高到渲染,但这根本没有帮助。http://social.msdn.microsoft.com/Forums/en-US/5eea6700-1c79-4da6-9b68-efa480ed3a36/simplify-wpf-dispatcher-calls?forum=rx
第 3 点与第 2 点相关。我尝试使用定时队列来解决这两个问题System.Debug.Stopwatch
。DataPackets 包含一个时间戳,这用于让它们在 Dispatcher 线程上以恒定速率通过。我怀疑这不会有太大帮助,因为 DispatcherRate 没有链接到渲染线程的刷新率。
我能做些什么来减少波动?我尝试了 LightningChart Ultimate,它应该要快得多。它确实具有更好的性能,并且不需要进行任何采样,它可以渲染每个数据点。LightningChart 提供的样本运行顺利,但它们在主线程中读取数据。当我在我们的多线程程序中实现他们的图表时,它仍然受到第 2 点和第 3 点的影响(事实上它比 Telerik chartview 贵得多。)
[更新]
经典错误。我的数据源使用 DispatcherTimer 来收集数据。将其更改为 Observable.Interval 极大地提高了性能。