zoukankan      html  css  js  c++  java
  • System.Windows.Forms.Timer定时器的“自毁”

    有些时候我们在让程序刚开始运行的时候完成一些初始化的工作,原来我也喜欢把这些代码写在窗体的Load事件中,但是我发现这样做很不好,因为工作量较大,或者使用远程数据库的时候会发现程序启动时会卡一下,用户体验很不好。

    界面设计的原则,界面线程Don't do heav work。

    后来我就把这些初始化的工作交给单独的线程执行,发现效果很好。但是后来CLR弄了个线程安全的限制,界面控件不允许跨线程更改,当然你也可以关闭这个,使用:

    在窗体的构造函数中加入这一句
    Control.CheckForIllegalCrossThreadCalls = false;
    子线程就可以直接访问窗体中的控件了,不过这样线程是非安全的.
    而默认Control.CheckForIllegalCrossThreadCalls=true;(捕获线程错误调用)
    这时可以用Invoke

    但是为了安全,不能这样。

    使用委托吧,这么多界面控件要更新,代码累死人呀!

    我就想到了System.Windows.Forms.Timer,这个更新界面可是安全的,但是问题也来了,它是通过Windows消息机制实现的,类似于VB或Delphi中的Timer控件,内部使用API  SetTimer实现的。它的主要缺点是计时不精确,而且必须有消息循环,Console  Application(控制台应用程序)无法使用。

    不精确无所谓,控制台应用程序与我没关系,可是必须循环就困难了,我想让它只执行一次,就行了!

    这个也简单,执行完之后,Timer自毁。使用:

    private void timer1_Tick(object sender, EventArgs e)
    {
    	//初始化工作代码
            timer1.Enabled = false;
       该方法有点小问题,看下面代码 }

    根据6楼 unkown 的意见(我刚刚测试过如果销毁放在后面确实会出现问题)
    也就是说你使用了timer 定时去在程序加载时更新主进程里的控件吗? 在计时器被触发的代码中 应该是第一件是就去销毁自己吧 再去更新控件!!
    修改成如下:

    在此感谢一下

    private void timer1_Tick(object sender, EventArgs e)
    {
            timer1.Enabled = false;
            //初始化工作代码
    }
    

      

    是不是很简单,这只是自己想到的小技巧,算是抛砖引玉。更希望各位技术大牛能够分享自己的技术与心得

  • 相关阅读:
    完全备份、差异备份以及增量备份的区别(转)
    Backup Exec Inventory 与Catalog的含义(转载)
    从客户端中检测到有潜在危险的Request.Form值的解决办法
    IQueryable与IEnumberable的区别(转)
    SQL递归查询(with cte as) 物料分解
    Http权威指南笔记(二) Http状态码大全
    Http权威指南笔记(一) URI URL URN 关系
    echarts在.Net中使用实例(二) 使用ajax动态加载数据
    echarts在.Net中使用实例(一) 简单的Demo
    sql显示12个月数据
  • 原文地址:https://www.cnblogs.com/wangluojisuan/p/2816525.html
Copyright © 2011-2022 走看看