如何检测属性10毫秒未被设置以在LiveCharts中绘制NaN值?
嘿,这个场景我之前做实时硬件监控图表的时候碰到过,给你几个实用的方案,核心思路就是跟踪属性最后被更新的时间戳,超时就自动补NaN:
第一步:调整数据类型(关键前提)
因为整数类型(int)没法存储NaN,而LiveCharts对double类型的NaN支持很好(会自动渲染成空白/断点),所以先把你的整数列表属性改成List<double>:
private List<double> _chartData; public List<double> ChartData { get => _chartData; set { _chartData = value; _lastUpdateTime = DateTime.Now; // 记录最后更新时间 OnPropertyChanged(nameof(ChartData)); // 通知UI刷新 } } private DateTime _lastUpdateTime = DateTime.Now;
方案一:用定时器定期检查超时
适合需要实时补NaN的场景,比如用WPF的DispatcherTimer(如果是WinForms就用System.Timers.Timer):
private DispatcherTimer _timeoutChecker; public YourViewModel() { _timeoutChecker = new DispatcherTimer(); _timeoutChecker.Interval = TimeSpan.FromMilliseconds(10); // 每10ms检查一次 _timeoutChecker.Tick += (s, e) => CheckAndFillNaN(); _timeoutChecker.Start(); } private void CheckAndFillNaN() { var timeSinceLastUpdate = DateTime.Now - _lastUpdateTime; if (timeSinceLastUpdate.TotalMilliseconds >= 10) { // 超时了,补一个NaN到数据末尾 if (_chartData == null) _chartData = new List<double>(); _chartData.Add(double.NaN); // 重置更新时间,避免无限触发补NaN _lastUpdateTime = DateTime.Now; OnPropertyChanged(nameof(ChartData)); } }
方案二:自定义可观察集合(更优雅)
如果你的数据是实时追加的,可以封装一个自动处理超时的集合,不用手动写定时器逻辑:
public class TimedChartCollection : ObservableCollection<double> { private DateTime _lastUpdateTime = DateTime.Now; private readonly DispatcherTimer _timeoutTimer; private readonly TimeSpan _timeout = TimeSpan.FromMilliseconds(10); public TimedChartCollection() { _timeoutTimer = new DispatcherTimer { Interval = _timeout }; _timeoutTimer.Tick += (s, e) => { if (DateTime.Now - _lastUpdateTime >= _timeout) { Add(double.NaN); _lastUpdateTime = DateTime.Now; } }; _timeoutTimer.Start(); } // 重写集合操作方法,自动更新最后更新时间 protected override void InsertItem(int index, double item) { base.InsertItem(index, item); _lastUpdateTime = DateTime.Now; } protected override void SetItem(int index, double item) { base.SetItem(index, item); _lastUpdateTime = DateTime.Now; } }
然后在ViewModel里直接用:
public TimedChartCollection ChartData { get; } = new TimedChartCollection();
之后硬件更新数据时,直接往ChartData里加值就好,超时会自动补NaN,完全不用额外处理。
注意事项
- 线程安全:如果硬件数据是从后台线程传入的,要确保更新集合/属性时切换到UI线程(WPF用
Dispatcher.Invoke),避免跨线程异常。 - 避免重复补NaN:每次补完NaN一定要重置
_lastUpdateTime,不然定时器会一直触发,疯狂加NaN。 - 数据长度控制:如果是长时间运行的监控,记得定期清理旧数据,避免列表无限增长导致内存问题。
内容的提问来源于stack exchange,提问作者Syed Saad
相关产品推荐
相关产品推荐

