簡體   English   中英

使用WPF和Oxyplot緩慢更新UI

[英]Slow updating of UI with WPF and Oxyplot

我要在這里完成的工作是我希望從CSV文件中獲取一些數據,這些數據是從一個文件夾復制並放入臨時文件夾的(因此我不會篡改原始文件)。

然后,我想從CSV文件中讀取所有數據,並使用Oxyplot中的Scatter Series(散點圖系列)在圖形上繪制最后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點並將其添加到圖表中。

也許我需要考慮一名后台工作者?

我可能會犯錯,如果我是我,我很想知道我應該朝哪個方向走! 我對編寫大型項目和必須實時運行的項目還很陌生。 請對我放輕松:)並預先感謝。

一些建議:

在您的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,我們已經將其用於各種高性能/大批量科學制圖應用程序(順便說一句,我不隸屬於它們!)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM