• Timer的使用


    一、Timer是定时器

    C#中常用的Timer有:

    System.Threading.Timer

    非常轻量级,用回调函数引发,在线程池执行;

    希望在另一个线程上定时执行后台任务;

    不建议用于Windows窗体,因为其回调不再用户界面线程上
    System.Timers.Timer

    精确。用事件方式触发,在线程池执行;

    是对Threading的Timer类的包装;

     
    System.Windows.Forms.Timer 基于Windows消息循环,用事件触发,在UI线程执行  
    System.Web.UI.Timer AJAX扩展,用于Web页面  
    System.Windows.Threading.DispatchTImer WPF程序使用,运行在UI线程上  
    自定义    

    注:Timer不要声明成局部变量,否则会被GC回收;

    二、Details

    1.System.Windows.Forms.Timer类型

    从这个定时器的命名空间可以看出,C#设计这个定时器的目的是为了方便程序员在Window Form中使用定时器。当一个System.Windows.Forms.Timer类被构造时,当前定时器会和当前线程进行关联。而当定时器的计时达到后,一个定时器消息将被插入到当前线程的消息队列中。当前线程逐一处理消息中的所有消息,并一一派发给各自的处理方法。事实上,System.Windows.Forms.Timer类型并没有涉及多线程的操作,定时器的设置、定时方法的执行都在同一个线程之上。(UI线程)

    也就因此,System.Windows.Forms.Timer并不能准确计时。当消息阻塞时,定时器的误差将非常大,因为定时器消息只能等待在前面的所有消息处理完后才能得到处理。但是因为System.Windows.Forms.Timer类型的定时器并不涉及多线程的操作,因此是线程安全的,不会发生回调方法重入的问题。

    2 System.Threading.Timer类型

    这个定时器类型的使用相对复杂,但同时它也是最优化的一个定时器类型。System.Threading.Timer的定时方法将不在工作者线程上执行。所有的对象有一个线程控制,当下一个定时到达时,该线程会负责在线程中获得一个新的工作者线程,用以执行相应的回调方法。

    虽然这个定时器是相对最优化的一个定时器类型,但是从其机制上来讲,其并不是线程安全的,可能会出现回调方法重入的问题。

    3 System.Timers.Timer类型

    这是一个相对较旧的类型。它和System.Threading.Timer一样,可以由工作者线程来执行回调方法,但同时它也可以在IDE环境中被拖到窗体控件上,这个时候它的行为非常类似于System.Windows.Forms.Timer类型,在消息过多时其定时并不准确。

    System.Timers.Timer可以视为System.Threading.Timer的一个包装,其类型设计相对古老,不建议使用该定时器。

    三、

    方法重入:

    博客园Demo

    • 方法重入,是一个有关多线程编程的概念:程序中,多个线程同时运行时,就可能发生同一个方法被多个进程同时调用的情况。当这个方法中存在一些非线程安全的代码时,方法重入会斗志数据不一致的情况,这个非常严重的bug。
    • Timer方法重入是,使用多线程计时器,一个Timer处理还没有完成,到了时间,另一Timer还会继续发生;
    • Timer的设计是尽量不做太耗时的工作。当无法避免要使用Timer,或者这项任务常会超时,解决办法是加锁:用用“lock(Object)”防止重入:

    //标记一个Timer正在执行,另一执行前发现前一个还没执行完,就放弃

    static int Finished= 0;

    public static void threadTimerCallback(Object obj)

    {

         if ( Finished== 0 )

         {

              Finished= 1;

              Thread.Sleep(2000);

              Finished= 0;

          }

    }

    lock比较好的实现多线程安全。

    (Vinno学习讨论会准备)

    Lionden

  • 相关阅读:
    BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
    BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
    HDU 1423 Greatest Common Increasing Subsequence ——动态规划
    BZOJ 3309 DZY Loves Math ——莫比乌斯反演
    POJ 1038 Bugs Integrated, Inc. ——状压DP
    POJ 3693 Maximum repetition substring ——后缀数组
    POJ 2699 The Maximum Number of Strong Kings ——网络流
    POJ 2396 Budget ——有上下界的网络流
    BZOJ 4650 [Noi2016]优秀的拆分 ——后缀数组
    源码安装python
  • 原文地址:https://www.cnblogs.com/lionden/p/timer_csharp.html
Copyright © 2020-2023  润新知