我再次向大家道歉一个简单的问题。我对Silverlight幕后的内容了解有限。

我有一个图表应用程序(Visiblox),用作滚动范围,每20毫秒更新一次,添加和删除一个点。用伪代码:

List<Point> datapoints= new List<Point>();
Series series = new Series(datapoints);
void timer_tick(){
  datapoints.Add(new Point);
  datapoints.RemoveAt(0);
  // no need to refresh chart, it does refresh automatically
}

在此图表工具中运行6系列时,它开始显示出一点点呆滞。将刻度更改为10ms没什么区别,图表以相同的速度更新,因此看来速度限制为20ms(UI或图表?)。

我尝试使用CompositionTarget.Rendering并获得了相同的结果:20毫秒以下的速度没有差异。

然后我不小心启用了两者,速度提高了一倍。因此,我测试了多个线程(2、3、4),并将速度提高了一倍,三倍和四倍。这还没有锁,因为我什至不知道我需要在哪个进程上生成锁,但是没有数据损坏或内存泄漏。

我的问题是,为什么在20ms时图表缓慢,在10ms时不能运行,但是在多线程时却快得离谱呢? UI刷新过程是否运行得更快?图表计算是否增加了一倍?还是可以限制单个DispatcherTimer的执行速度有多快?

谢谢!

编辑:我有嵌入式编码的背景,所以当我想到线程和时序时,我立即想到切换硬件中的引脚并连接一个范围来测量过程长度。我对C#中的线程是陌生的,没有任何引脚可以连接作用域。有没有办法以图形方式查看线程的时间安排?

最佳答案

我认为这里的关键是要意识到,Silverlight默认情况下以60fps的最大帧速率渲染(可通过您的MaxFrameRate属性进行自定义)。这意味着DispatcherTimer滴答声将每秒最多触发60次。此外,所有渲染工作也都在UI线程上进行,因此DispatcherTimer以最佳的方式进行绘图,如先前的海报所指出的那样触发。

通过添加三个计时器执行的操作的结果是,每个事件循环触发3次而不是触发3次“添加数据”方法,因此看起来您的图表运行得更快,但实际上帧速率大约是相同。您只需使用一个DispatcherTimer即可获得相同的效果,并且只需在每个Tick上添加3倍的数据即可。您可以通过挂接到CompositionTarget.Rendering事件并在那里并行计算帧速率来验证这一点。

先前提出的ObservableCollection点是一个很好的方法,但是在Visiblox中,有一些魔术可以尝试减轻这种影响,因此,如果您以非常快的速率添加数据,则图表更新将以渲染循环和不必要的重新渲染将被丢弃。

另外,关于与IDataSeries的ObservableCollection实现绑定(bind)的观点,您完全可以自己自由实现IDataSeries接口(interface),例如,通过简单的List对其进行支持。请注意,显然,如果您这样做,图表将不会在数据更改时自动更新。您可以通过调用Chart.Invalidate()或更改手动设置的轴范围来强制更新图表。

10-08 12:38