1

ここで達成しようとしているのは、あるフォルダーからコピーして一時フォルダーに入れる CSV ファイルからデータを取得することです (元のファイルを改ざんしないようにします)。

次に、CSV ファイルからすべてのデータを読み込み、Oxyplot の散布シリーズを使用してグラフに最後の 2000 データ ポイントをプロットします (200 ミリ秒ごとに新しいデータをチェックしたいので、Dispatcher Timer を使用しました)。私が抱えている問題は、プロットの最初の数回の更新が見栄えがよく、希望どおりに正確にプロットされることです...ただし、おそらく12回の更新の後、グラフが更新されないか、更新が非常に遅くなり、UIが無反応。

以下は、プロジェクトのこの部分の私のコードです...

    public MainWindow()
    {
        viewModel = new View_Model.MainWindowModel();
        DataContext = viewModel;

        CompositionTarget.Rendering += CompositionTargetRendering;

        InitializeComponent();
    }

    private void AutoUpdateGraph()  //begins when a check box IsChecked = true
    {
        sw.Start();
        System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 200);
        dispatcherTimer.Start();
    }

    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        SleeveData sd = new SleeveData();          //class to deal with the data
        FileManagement fm = new FileManagement();  //class to manage the files

        string date = fm.GetDate();                //get the current date to use in finding the 
                                                   //most recent CSV file

        _newPath = fm.InitialFileSetup(date);      //create a new path for the temp file

        fm.RewriteFile(_newPath);                  //write the temp file to the temp path

        if (fm.IsFileLocked(_newPath) == false)   //checking if the file is being written to
        {
            IEnumerable<SleeveData> newSD = sd.GetMostRecentCSVData(_newPath); //getting the latest data from the temp file

            viewModel.LoadData(newSD); //updating the data on the graph
        }
    }

そして、これが MainWindowModel の LoadData メソッドです...

    public void LoadData(IEnumerable<SleeveData> newData)
    {
        var scatterSeries1 = new OxyPlot.Series.ScatterSeries
        {
            MarkerSize = 3,
            Title = string.Format("Sleeve Data"),
        };

        int j = 0;

        var zeroBuffer = new List<float>(new float[2000]);
        var fDiaDataBuffer = zeroBuffer.Concat((newData.Select(x => x.fDiameter).ToList())).ToList();
        var iDiaDataBuffer = zeroBuffer.Concat((newData.Select(x => x.IDiaMax).ToList())).ToList();

        for (int i = fDiaDataBuffer.Count - 2000; i <= fDiaDataBuffer.Count - 1; i++)
        {
            scatterSeries1.Points.Add(new ScatterPoint(j, fDiaDataBuffer[i]));
            j++;
        }

        PlotModel.Series.Clear();
        PlotModel.Series.Add(scatterSeries1);
    }

最新の 2000 ポイントを取得してグラフに追加するために、いくつかのファンキーなことをしています。

多分私はバックグラウンドワーカーを考慮する必要がありますか?

私はこれについてすべて間違っているかもしれません。もしそうなら、どちらの方向に進むべきか知りたいです! 私は、これほど大規模で、リアルタイムで実行する必要があるプロジェクトのコーディングにかなり慣れていません。私に気楽に行ってください:)そして前もって感謝します。

4

1 に答える 1

1

いくつかの提案:

LoadData() メソッドでストップウォッチを使用して、所要時間を確認します。これらのファイルにどれだけのデータが含まれているかはわかりませんが、Linq のものの中には、最適化の恩恵を受ける可能性があるように見えるものがあります。同じデータセットに多くのデータがToLists()繰り返されています。Selectsこのようなもの:

var sw = new Stopwatch();
sw.Start();

... do your stuff

Debug.WriteLine(sw.ElapsedMilliseconds);

また、タイマー デリゲートでストップウォッチを試して、200 ミリ秒以上かかる場合に備えて、「サイクル」全体にかかる時間を確認することもできます。DispatcherTimer が再入可能性に悩まされる可能性があるかどうかはわかりません。つまり、前の「ティック」が完了する前にタイマーが再び起動し、パフォーマンスが低下します。

問題は、グラフ作成コンポーネントにある可能性があります。大規模な WPF DataGrid を操作するときに同様の問題が発生しました。データの作成は特に負担ではありません。時間がかかるのはレンダリングです。LoadData() の最後で、チャート シリーズをクリアしてから再入力しているのがわかります。大規模な DataGrid のデータ ソースでこれを行うと、Clear() の後にレンダリングされ、データの再入力後に再度レンダリングされるため、「二重の打撃」が生じることがわかりました。私は OxyPlot に精通していませんが、可能であれば別のアプローチを見つけることができるかどうかを確認してください。たとえば、消去して再度追加するのではなく、シリーズを再利用します。

パフォーマンスの低下が OxyPlot であることが判明した場合、別のチャート コンポーネントを購入するオプションはありますか? SciChart は、さまざまな高性能/大量の科学チャート作成アプリケーションに使用してきました (ちなみに、私は SciChart と提携していません!)。

于 2014-08-19T09:19:20.003 に答える