C#三种定时器的介绍及用法

概述

在.NET Framework里面提供了三种Timer(只考虑Winform)

① System.Windows.Forms.Timer

② System.Timers.Timer

③ System.Threading.Timer

现分述如下:

1.System.Windows.Forms.Timer

介绍

  System.Windows.Forms.Timer基于Windows消息循环,用事件方式触发,在界面线程执行;是使用得比较多的Timer,Timer Start之后定时(按设定的Interval)调用挂接在Tick事件上的EvnetHandler。在这种Timer的EventHandler中可 以直接获取和修改UI元素而不会出现问题–因为这种Timer实际上就是在UI线程自身上进行调用的。

  • 它是一个基于Form的计时器
  • 创建之后,你可以使用Interval设置Tick之间的跨度,用委托(delegate)hook Tick事件
  • 调用Start和Stop方法,开始和停止
  • 完全基于UI线程,因此部分UI相关的操作会在这个计时器内进行
  • 长时间的UI操作可能导致部分Tick丢失

用法

        #region Timer控件定时操作
        private void TimerInit()
        {
            timer_Name.Enabled = true;
            timer_Name.Interval = 200;//200毫秒1次
            timer_Name.Tick += new EventHandler(timer_Name_Tick);
            timer_Name.Start();
        }

        private void timer_Name_Tick(object sender, EventArgs e)
        {
            //关闭定时器防止多次触发
            timer_Name_Monitor.Enabled = false;
            //要定时执行的方法 
            TimerNameWorking();
            //启动定时器
            timer_Name_Monitor.Enabled = true;
        }
       #endregion

  Windows计时器是为单线程环境设计的,其中,UI 线程用于执行处理。它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。
  当定时器触发时,Windows把一个定时器消息插入到线程消息队列中。调用线程执行一个消息泵提取消息,然后发送到回调方法中(这里的timer_Name_Tick方法)。而这些都是单线程进行了,所以在执行回调方法时UI会假死。所以使用这个控件不宜执行计算受限或IO受限的代码,因为这样容易导致界面假死,而应该使用多线程调用的Timer。另外要注意的是这个控件时间精度不高,精度限定为 55 毫秒。

2.System.Timers.Timer

介绍

  System.Timers.Timer类:定义一个System.Timers.Timer对象,然后绑定Elapsed事件,通过Start()方法来启动计时,通过Stop()方法或者Enable=false停止计时。AutoReset属性设置是否重复计时(设置为false只执行一次,设置为true可以多次执行)。Elapsed事件绑定相当于另开了一个线程,也就是说在Elapsed绑定的事件里不能访问其它线程里的控件(需要定义委托,通过Invoke调用委托访问其它线程里面的控件)。

用法

长时间任务必须防止重复调用,否则定时器会在上次任务未执行完就再次开线程执行任务

        System.Timers.Timer timerName= new System.Timers.Timer();
        private void  timerNameInit() 
        {
            timerName.Enabled = true;
            timerName.Interval = 1000;//执行间隔时间,单位为毫秒    
            timerName.Start();
            timerName.Elapsed += new System.Timers.ElapsedEventHandler(timerName_Elapsed);
        }
        private void timerName_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //关闭定时器防止多次触发
            timerName.Stop(); 
            //要定时执行的方法          
            TimerNameWorking();
            //启动定时器
            timerName.Start();
        }

3.System.Threading.Timer

介绍

  System.Threading.Timer类:定义该类时通过构造函数进行初始化,执行的方法也是新开一个线程。

用法(正确用法)

System.Threading.Timer的正确用法如下:

       //定义Timer类
        System.Threading.Timer timerName;
        /// <summary>
        /// 初始化Timer类
        /// </summary>
        private void timerNameInit()
        {
            //定时器在时间间隔过后仅打勾一次,然后在回调函数中工作完成后更改计时器,不需要锁定机制,没有并发性。
            timerName = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
        }

        /// <summary>
        /// 定时到点执行的事件
        /// </summary>
        /// <param name="value"></param>
        private void TimerCall(object value)
        {
             // Long running operation
             //定时器将在下一个时间间隔+长时间运行时间后触发下一个回调
             timerName.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
        }
        //如果需要在N毫秒的时间内运行计时器,那么建议使用秒表来测量长时间运行的操作时间,然后适当调用Change方法:
        private void TimerCall(Object state)
        {
            Stopwatch watch = new Stopwatch();

            watch.Start();
            // Long running operation

             timerName.Change(Math.Max(0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds), Timeout.Infinite);
        }
    }
}

总结

  • System.Windows.Forms.Timer基于Windows消息机制,在UI线程执行,不适合执行长时间任务,建议在与界面控件操作相关的任务中使用
  • System.Timers.Timer基于事件,在线程池中执行,上次任务的是否执行完毕不影响下次任务的开始执行,不建议单个任务而且也有一些bug
  • System.Threading.Timer基于回调函数,只能定时执行单个任务。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值