使用PathGeometry的WPF实时图表性能

时间:2011-03-11 23:46:29

标签: wpf performance charts pathgeometry

我正在尝试实现一个可以处理实时数据的图表,该图表每1毫秒发布一次。我轮询50ms的数据,这样我就不会每隔一毫秒重绘一次屏幕。我在Canvas上使用PathGeometry来添加线段。随着重绘速度越来越慢,我总是看到帧率稳定下降。我不认为大约10,000点的Line对于我的计算机渲染是如此困难。有什么我做错了吗?或者是否有其他一些设计理念可能更擅长处理WPF中的实时数据?

在ViewModel中我有:

public PointCollection LinePoints;

在视图中我听到这个集合正在被更改并添加线段:

_viewModel.LinePoints.Changed += LinePoints_Changed;

void LinePoints_Changed(object sender, System.EventArgs e)
{
    while (_viewModel.LinePoints.Count - 1 > pathFigure.Segments.Count)
    {
        // pathFigure is part of the PathGeometry on my canvas
        pathFigure.Segments.Add(new LineSegment(_viewModel.LinePoints[pathFigure.Segments.Count], true));
    }
}

出于模拟目的,我使用BackgroundWorker注入点:

void addPointsWorker_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker bw = sender as BackgroundWorker;
    DateTime startTime = DateTime.Now;

    int numPointsAdded = 0;

    while (!bw.CancellationPending && (DateTime.Now - startTime).Seconds < 10)
    {
        List<Point> points = new List<Point>();

        for (int i = 0; i < 50; i++)
        {
            Math.Sin(numPointsAdded++/(500*Math.PI))));
        }

        System.Threading.Thread.Sleep(50);

        bw.ReportProgress(0, points);
    }
}

public void addPointsWorker_ProgressChanged(List<Point> pointsToAdd)
{
    foreach(Point point in pointsToAdd)
    {
        // triggers CollectionChanged which will add the line segments
        ViewModel.LinePoints.Add(point);
    }
}

随着减速,我也遇到了UI无响应。我认为这是因为我正在制作太多的ReportProgress调用并填充消息泵,但如果我可以解决慢速渲染问题,我认为这个问题也会消失。我愿意接受任何建议!

2 个答案:

答案 0 :(得分:2)

我有两点建议:

  1. 确保您的收藏集仅包含将呈现给屏幕的点。一个简单的方法是使用队列,并在添加更多点时从前面删除。我怀疑所有10,000点都需要一次渲染。
  2. 如果仍然无法获得所需的性能,则可能需要使用较低级别的绘图机制。 StreamGeometry将首先尝试。之后,WriteableBitmap将在WPF中提供最佳性能。

答案 1 :(得分:0)

经过一段时间的调整后,我发现查理是最好的解决方案。我还发现,每次添加一个点时,不是使用LineSegment,而是使用具有50个左右数据点的PolyLineSegment,我已经排队了,这对性能有好处。

然而,它并没有延迟发生的不可避免的减速。但是使用PolyLineSegment与最后几百甚至上千点的组合,可以在显示尽可能多的数据的同时获得最佳性能。