DevExpress 性能优化之 ChartControl:方法一

▪ 场景:

采用 ChartControl:XYDiagram2D(折线图),从示波器里实时采集 600 个点数据并显示在 折线图 中。

▪ 问题:

假设我们实时采集数据的时间间隔是 0.5 秒,但是由于 ChartControl 控件 重绘这 600 个点所需的时间大于这个时间间隔,并且随着程序的执行内存的消耗,重绘时间将还会大一点,从而导致了 折线图 的数据大大延迟于示波器的实时数据。

同时由于 ChartControl 控件 一直占用主UI线程,导致整个界面响应卡顿。

▪ 解决

使用 .BeginInit().EndInit() 的方法来避免不必要的更新,从而缩短重绘的时间。

使用时需要注意,如果你已经明确经常更新的是折线图的某个部位(比如某条折线条,某个条线条的点集合等等),那么最好直接使用其对应对象的 .BeginInit().EndInit(),这样性能将提高更多。

例如: 实时更新第2条的折线条点集合,最好直接调用其对象的 uiChart.Diagram.Series[1].Points.BeginInit() / .EndInit(),这样能明确让系统不去更新折线图的其他UI部位,性能更高。

当然你可以使用 uiChart.BeginInit() / .EndInit() ,但是其效果不如上面的代码

▪ 源码

/// <summary>
/// 定时器集合
/// </summary>
private Dictionary<string, Timer> appTimers = null;
private Dictionary<string, bool> appTimerLocks = null;
        
/// <summary>
/// 构造函数
/// </summary>
public MainWindow()
{
    InitializeComponent();

    // 初始化
    this.appTimers = new Dictionary<string, Timer>();
    this.appTimerLocks = new Dictionary<string, bool>();

    // 图表初始化
    uiChart_Init();
    
    // 图表定时器启用
    this.appTimers.Add("uiChart_Timer", new Timer(this.uiChart_Timer,null,0,500));
    this.appTimerLocks.Add("uiChart_Timer", false);
}


/// <summary>
/// 图表初始化
/// </summary>
private void uiChart_Init()
{
    // 此处是初始化图表的一些显示参数
    // 代码忽略,详见《DevExpress 控件快速上手之 ChartControl:XYDiagram2D(折线图)》
}


/// <summary>
/// 图表的定时器回调函数
/// </summary>
/// <param name="o"></param>
private void uiChart_Timer( object o )
{
    // 如果定时器正处于锁定状态,那么结束回调函数
    // 这样做主要作用就是确保无论定时器触发时间有多短,都可以保证同一时刻只能执行一个回调函数
    if( this.appTimerLocks.ContainsKey("uiChart_Timer") && this.appTimerLocks["uiChart_Timer"] == true ) return;

    // 定时器加锁
    this.appTimerLocks["uiChart_Timer"] = true;

    // 初始化
    Random random = new Random();
    SeriesPointCollection seriesPointCollection = new SeriesPointCollection();
    for( int i = 0; i <= 600; i++ ) seriesPointCollection.Add(new SeriesPoint(i,random.Next(-10,10)));  // 生成 100个(X轴) 0~10 随机值(Y轴)的点

    // UI 应用
    this.Dispatcher.Invoke(new Action(()=> {
        uiChart.Diagram.Series[0].Points.BeginInit(); // 【优化的代码】效果更好
        uiChart.Diagram.Series[0].Points.Clear();
        uiChart.Diagram.Series[0].Points.AddRange(seriesPointCollection);
        uiChart.Diagram.Series[0].Points.BeginInit(); // 【优化的代码】效果更好
    }));

    // 定时器解锁
    this.appTimerLocks["uiChart_Timer"] = false;
}

▪ 总结

效果提升明显。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值