繁体   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