0

我正在使用 MS VS 2015 中的 Prism 6 编写 C# WPF 纯 MVVM 应用程序。我需要显示一个实时笛卡尔折线图,其中包含大量连续添加到系列中的点。在“A”棱镜模块中,我每 1000 毫秒通过串行端口汇集外部设备的寄存器,并将这些数据放入共享缓冲区(使用System.ThreadingTimer)。

在 'B' Prism 模块中,我以 1000 毫秒的间隔汇集这个共享缓冲区(使用System.Windows.Threading.DispatcherTimer它)。DispatcherTimer 的每个滴答声我都从共享缓冲区中获取数据,从数据中创建数据点并将此数据点放入ChartValues<T>集合中以在我的图表中删除此数据点。下面是我在“B”棱镜模块中查看模型的 C# 代码。

public class DeviceReadingViewModel : BindableBase, IConfirmNavigationRequest
{
    /// <summary>
    /// Coordinates for chart's data-point.
    /// </summary>
    public class ChartPoint
    {
        /// <summary>
        /// X axis value.
        /// </summary>
        public DateTime X;
        /// <summary>
        /// Y axis value.
        /// </summary>
        public double Y;
    }

    // X-axis maximum.
    private double _axisMax;
    public double AxisMax
    {
        get { return this._axisMax; }
        set { this.SetProperty(ref this._axisMax, value); }
    }

    // X-axis minimum
    private double _axisMin;
    public double AxisMin
    {
        get { return this._axisMin; }
        set { this.SetProperty(ref this._axisMin, value); }
    }

    // Constructor
    public DeviceReadingViewModel()
    {
        // Use DateTime values for X-axis, and values from outer device register for Y-axis.
        var mapper = Mappers.Xy<ChartPoint>().X(model => model.X.Ticks).Y(model => model.Y);
        // Save the mapper.
        Charting.For<ChartPoint>(mapper);
        // Chart's data-point collection.
        Values = new ChartValues<ChartPoint>();
        // Set format for X.
        DateTimeFormatter = value => new DateTime(DateTime.Now.Ticks).ToString("hh:mm:ss");
        // Set unit interval on X-axis as 2 seconds.
        AxisStep = TimeSpan.FromSeconds(2).Ticks;
        // Initialize System.Windows.Threading.DispatcherTimer.
        this.Timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
        this.Timer.Tick += Timer_Tick;
    }

    // Timer tick handler.
    private void Timer_Tick(object sender, EventArgs e)
    {
        // Create new data-point for chart.
        ChartPoint chartData = new ChartPoint();
        chartData.X = DateTime.Now;
        // Here GlobalStaticMembers.GasVelocityBuffer is shared buffer comprising new value from outer device register.
        chartData.Y = GlobalStaticMembers.GasVelocityBuffer;
        // Set minimum and maximum on X-axis:
        if (AxisMin == 0 && AxisMax == 0)
        {
           // This operation is performed once.
           AxisMax = chartData.X.Ticks + TimeSpan.FromSeconds(60).Ticks;
           AxisMin = chartData.X.Ticks;
        }    
        else
        {
            if (this.Values.Count >= 60)
            {
                // And this operation is performed every second, after the number of points to exceed 60 points.
                this.AxisMin = this.AxisMin + TimeSpan.FromSeconds(1).Ticks;
                this.AxisMax = this.AxisMax + TimeSpan.FromSeconds(1).Ticks;
            }
        }
        // Draw data-point in the chart.
        this.Values.Add(chartData);
    }

    // Timer to pool shared buffer.
    public DispatcherTimer Timer { get; set; }
    // X-axis value formatter.
    public Func<double, string> DateTimeFormatter { get; set; }
    // The price of the unit interval.
    public double AxisStep { get; set; }
    // Chart data-point colection.
    public ChartValues<ChartPoint> Values { get; set; }
}

下面是 Prism UserControl 中 LiveCharts 的 XAML:

<lvc:CartesianChart Grid.Row="0" Grid.Column="0">
    <lvc:CartesianChart.Series>
       <lvc:LineSeries Values="{Binding Values}" PointGeometrySize="10" StrokeThickness="2"/>
    </lvc:CartesianChart.Series>
    <lvc:CartesianChart.AxisX>
       <lvc:Axis LabelFormatter="{Binding DateTimeFormatter}" MaxValue="{Binding AxisMax}" MinValue="{Binding AxisMin}" DisableAnimations="True">
          <lvc:Axis.Separator>
              <lvc:Separator Step="{Binding AxisStep}"/>
          </lvc:Axis.Separator>
       </lvc:Axis>
    </lvc:CartesianChart.AxisX>
</lvc:CartesianChart>

我的问题是,当我每 1000 毫秒使用 then(工作 8 - 10 分钟后)创建数据点并将其添加到系列时DispatcherTimer,我的应用程序开始变慢并挂起。我需要在异步模式下使用 LiveCharts 以避免减速和挂起应用程序的工作。昨天我花了一整天的时间寻找 LiveCharts 在异步模式下工作的例子。我曾经使用谷歌,但我没有发现任何值得的东西。

我是 LiveCharts 的初学者,因为我只是第二次使用 LiveCharts。如何让 LiveCharts 在异步模式下工作以避免减速和挂起我的应用程序?为什么我的应用程序在工作 7-8 分钟后会变慢并挂断?我做错了什么?

4

0 回答 0