如何让LiveCharts在异步模式下工作?

时间:2016-08-01 07:21:11

标签: c# wpf mvvm livecharts

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

在'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>

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

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

0 个答案:

没有答案