我正在使用 MS VS 2015 中的 Prism 6 编写 C# WPF 纯 MVVM 应用程序。我需要显示一个实时笛卡尔折线图,其中包含大量连续添加到系列中的点。在“A”棱镜模块中,我每 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>
我的问题是,当我每 1000 毫秒使用 then(工作 8 - 10 分钟后)创建数据点并将其添加到系列时DispatcherTimer
,我的应用程序开始变慢并挂起。我需要在异步模式下使用 LiveCharts 以避免减速和挂起应用程序的工作。昨天我花了一整天的时间寻找 LiveCharts 在异步模式下工作的例子。我曾经使用谷歌,但我没有发现任何值得的东西。
我是 LiveCharts 的初学者,因为我只是第二次使用 LiveCharts。如何让 LiveCharts 在异步模式下工作以避免减速和挂起我的应用程序?为什么我的应用程序在工作 7-8 分钟后会变慢并挂断?我做错了什么?