• .net 定时器的使用(转)


    在Framework中存在着4种定时器:其中分为两类,

    多线程计时器

    1:System.Threading.Timer

    2:System.Timers.Timer

    特殊目的的单线程计时器:

    1:System.Windows.Forms.Timer(Windows Forms Timer)

    2:System.Windows.Threading.DispatcherTimer(WPF timer);

    多线程计时器比较强大,精确,而且可扩展性强;

    单线程计时器比较安全,对于更新 Windows Forms controls或者WPF这种简单任务来说更方便。

     
    System.Timers.Timer aTimer = new System.Timers.Timer();aTimer.Elapsed += new ElapsedEventHandler(theout);  //到达时间的时候执行事件;aTimer.Interval = 100000; // 设置引发时间的时间间隔 此处设置为1秒(1000毫秒)aTimer.AutoReset = true;//设置是执行一次(false)还是一直执行(true);aTimer.Enabled = true; //是否执行System.Timers.Timer.Elapsed事件;aTimer.Start(); //开始aTimer.Stop();  //停止 

    System.Threading.Timer是最简单的多线程计时器。在下面的例子中,定时器在5秒后开始定时1秒的调用Tick方法。

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public static void Main ()  
    2.  {  
    3.      //5秒后开始运行,接着每隔1秒的调用Tick方法  
    4.      Timer tmr = new Timer(Tick, "tick...", 5000, 1000);  
    5.      Console.ReadLine();  
    6.      tmr.Dispose();  
    7.  }  
    8.  static void Tick(object data)  
    9.  {  
    10.      Console.WriteLine(data);  
    11.  }  

    .net framework提供的另一个计时器System.Timers.Timer.简单的对System.Threading.Timer进行了包装。增加了下面几个特性。

    1. 实现了Component,所以可以在设计器显示。
    2. 代替Change方法的一个Interval属性
    3. 代替callback委托的一个Elapsed事件
    4. 启动和停止timer的Enabled属性,默认是false。
    5. 为了避免Enabled造成混乱,提供了Start和Stop方法。
    6. 是否在每次指定的间隔结束时引发Elapsed时间,还是仅间隔第一次结束后运行的AutoReset属性。
    7. 在WPF或Windows Forms中安全的调用方法的SynchronizingObject对象。
    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public static void MainThread()  
    2.         {  
    3.             Timer tmr = new Timer();  
    4.             tmr.Interval = 500;  
    5.             tmr.Elapsed += new ElapsedEventHandler(tmr_Elapsed);  
    6.             tmr.Start();  
    7.             Console.ReadLine();  
    8.             tmr.Stop();  
    9.             Console.ReadLine();  
    10.             tmr.Start();  
    11.             Console.ReadLine();  
    12.             tmr.Dispose();  
    13.         }  
    14.   
    15.         static void tmr_Elapsed(object sender, ElapsedEventArgs e)  
    16.         {  
    17.             Console.WriteLine("Tick...");  
    18.         }  

    public static void MainThread()
            {
                Timer tmr = new Timer();
                tmr.Interval = 500;
                tmr.Elapsed += new ElapsedEventHandler(tmr_Elapsed);
                tmr.Start();
                Console.ReadLine();
                tmr.Stop();
                Console.ReadLine();
                tmr.Start();
                Console.ReadLine();
                tmr.Dispose();
            }

            static void tmr_Elapsed(object sender, ElapsedEventArgs e)
            {
                Console.WriteLine("Tick...");
            }

    单线程计时器:

    1:System.Windows.Forms.Timer(Windows Forms Timer)

    2:System.Windows.Threading.DispatcherTimer(WPF timer);

    单线程计时器是被设计成属于他们执行环境的计时器,如果你在一个Windows服务应用程序中使用Windows Forms的Timer,timer 事件并不会被触发,只有在对应的环境下才会被触发。

    像System.Timers.Timer一样,他们也提供了相同的成员(Interval,Tick,Start,Stop),但是他们内部的工作原理不同,

    WPF和Windows Forms的计时器使用消息循环机制来取代线程池产生消息的机制。

    这意味着Tick事件总是在创建timer的那个线程上执行,同时也意味着如果上一个Tick消息还未被处理,即使时间超过了间隔时间,在消息循环中也只存在一个Tick消息。

    下面是它们的优点:

    1. 你可以忘记线程安全。
    2. 一个Tick事件在前一个Tick事件被处理完毕前不会被触发。
    3. 你可以直接在Tick事件处理代码中更新控件,不需要调用Control.Invoke或Dispatcher.Invoke.

    看下在Winform中使用单线程定时器的效果:

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. 基于Windows消息循环的单线程计时器  
    2.         private System.Windows.Forms.Timer timer = new Timer() { };  
    3.   
    4.         public Form1()  
    5.         {  
    6.             InitializeComponent();  
    7.   
    8.             timer.Tick += new EventHandler(timer_Tick);  
    9.             timer.Enabled = true;  
    10.         }  
    11.   
    12.         void timer_Tick(object sender, EventArgs e)  
    13.         {  
    14.             //模拟的做一些耗时的操作  
    15.             System.Threading.Thread.Sleep(2000);  
    16.         }  


    如果运行上面的代码,会发现UI界面响应速度很慢,

    原理上面已经介绍了:单线程计时器基于Windows消息循环,应用程序会同步的处理计时器的消息。

    解决这个问题的方法是使用多线程计时器:只要修改代码使用多线程计时器即可:

    [csharp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. //使用多线程计时器  
    2. private System.Timers.Timer timer = new System.Timers.Timer();  
    3.   
    4. public Form1()  
    5. {  
    6.     InitializeComponent();  
    7.   
    8.     timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);  
    9.     timer.Enabled = true;  
    10. }  
    11.   
    12. void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)  
    13. {  
    14.     //模拟的做一些耗时的操作  
    15.     System.Threading.Thread.Sleep(2000);  
    16. }  


    上面的例子告诉我们单线程计时器的缺点:

    除非Tick事件的处理代码执行的非常快,否则UI界面会变得响应很慢。 

    所以 WPF和Windows Forms的计时器都非常适合小任务,尤其是界面更新的任务。例如时钟和计数显示。否则,你需要一个多线程计时器。
    愿你我既可以朝九晚五,也可以浪迹天涯;愿你我既可以拈花把酒,也能围炉诗书茶。
  • 相关阅读:
    Leetcode Palindrome Linked List
    Leetcode Delete Node in a Linked List
    Leetcode Ugly Number
    Python 列表解析
    Python 生成器以及应用
    Python 迭代器协议以及可迭代对象、迭代器对象
    Python 装饰器
    Python 函数的嵌套
    Python 闭包函数
    Python 名称空间与作用域
  • 原文地址:https://www.cnblogs.com/xiaoheihei/p/6474936.html
Copyright © 2020-2023  润新知