1

我正在尝试实现一个可以处理实时数据的图表,该数据每 1 毫秒出现一次。我轮询 50 毫秒的数据,这样我就不会每毫秒都重绘屏幕。我在画布上使用 PathGeometry 添加线段。我总是看到帧速率稳步下降,因为重绘变得越来越慢。我没想到我的电脑渲染一条大约有 10,000 点的线会如此困难。有什么我做错了吗?或者是否有其他一些设计理念可能更擅长处理 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 调用并填充了消息泵,但如果我能解决缓慢的渲染,我认为这个其他问题也会消失。我愿意接受任何建议!

4

2 回答 2

2

我有两个建议:

  1. 确保您的集合仅包含将呈现到屏幕上的点。一个简单的方法是使用队列并在添加更多点时从前面移除。我怀疑是否需要一次渲染所有 10,000 个点。
  2. 如果这仍然无法为您提供所需的性能,您可能需要使用较低级别的绘图机制。StreamGeometry将是第一个尝试的方法。之后,WriteableBitmap将在 WPF 中提供最佳性能。
于 2011-03-12T01:23:02.470 回答
0

经过一段时间的调整,我发现 Charlie's 是最好的解决方案。我还发现,不是每次添加一个点时都使用 LineSegment,而是使用 PolyLineSegment 和我已经在排队的 50 个左右的数据点可以提高性能。

然而,它并没有延迟不可避免的放缓。但是使用 PolyLineSegment 与仅最后几百甚至几千点的组合给了我最好的性能,同时显示尽可能多的数据。

于 2011-03-17T21:51:50.363 回答