1

1ミリ秒ごとのリアルタイムデータを処理できるチャートを実装しようとしています。50 ミリ秒のデータをポーリングして、1 ミリ秒ごとに画面を再描画しようとしないようにします。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 の呼び出しが多すぎてメッセージ ポンプがいっぱいになっているためだと考えましたが、遅いレンダリングを解決できれば、この他の問題も解消されると思います。私はどんな提案にもオープンです!

4

2 に答える 2

2

2 つの提案があります。

  1. コレクションには、画面にレンダリングされるポイントのみが含まれていることを確認してください。これを行う簡単な方法は、キューを使用して、より多くのポイントが追加されるにつれて前面から削除することです。10,000 ポイントすべてを一度にレンダリングする必要があるとは思えません。
  2. それでも必要なパフォーマンスが得られない場合は、低レベルの描画メカニズムを使用することをお勧めします。StreamGeometryは、最初に試すものです。その後、WriteableBitmapは WPF で可能な限り最高のパフォーマンスを提供します。
于 2011-03-12T01:23:02.470 に答える
0

少し時間をかけて調整した後、Charlie が最適なソリューションであることがわかりました。また、ポイントが追加されるたびに LineSegment を使用する代わりに、既にキューに入れている 50 ほどのポイントのデータで PolyLineSegment を使用すると、パフォーマンスが驚くほど向上することも発見しました。

ただし、発生する避けられない減速を遅らせることはありません。しかし、PolyLineSegment と最後の数百または数千のポイントのみを組み合わせて使用​​すると、可能な限り多くのデータを表示しながら、最高のパフォーマンスが得られました。

于 2011-03-17T21:51:50.363 に答える