1

我在这里想要完成的是我想从一个 CSV 文件中获取一些数据,这些数据我从一个文件夹中复制并放入一个临时文件夹中(所以我不会篡改原始文件)。

然后我想从 CSV 文件中读取所有数据,并使用 Oxyplot 中的 Scatter Series 在图表上绘制最后 2000 个数据点(我希望它每 200 毫秒检查一次新数据,所以我使用了调度程序计时器)。我遇到的问题是情节的前几次更新看起来很棒,并且它完全按照我想要的方式绘制......但是,在可能 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 DataGrids 时,我也遇到过类似的问题——创建数据并不是特别费力——渲染需要时间。在 LoadData() 结束时,我看到您清除图表系列,然后重新填充它。我发现对大型 DataGrid 的数据源执行此操作会产生“双重打击”,因为它在 Clear() 之后呈现,然后在重新填充数据后再次呈现。我对 OxyPlot 不熟悉,但如果可行的话,看看你是否可以找到一种替代方法,例如重新使用该系列而不是清理并再次添加。

如果性能不佳确实是 OxyPlot,是否可以选择购买不同的图表组件?我可以彻底推荐 SciChart,我们一直在将其用于各种高性能/大容量科学图表应用程序(顺便说一句,我不隶属于它们!)。

于 2014-08-19T09:19:20.003 回答