• C#-Forms.Timer、Timers.Timer、Threading.Timer的比较和使用


    在.NET Framework里面提供了三种Timer

    ① System.Windows.Forms.Timer

    ② System.Timers.Timer

    ③ System.Threading.Timer

    一、System.Windows.Forms.Timer

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

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


    using System.Windows.Forms.Timer;
    实现按用户定义的时间间隔引发事件的计时器。此计时器最宜用于 Windows 窗体应用程序中,并且必须在窗口中使用。

    这个类在Windows应用程序中使用,用来定期把WM_TIMER消息放到程序的消息队列中。当程序从队列中获取消息后,它会在主用户接口线程中同步处理,这对Windows应用程序来说非常重要。精度限定:55ms(引用自图书《C#图解教程(第四版)》439页)

    定时器任务执行时间比较长时,不建议使用Forms.Timer,会出现界面假死现象,建议使用Timers.Timer,不会界面假死,并且精度更高!

    示例程序:(解释Forms.Timer和Winform的窗体共用一个线程,现象:界面假死)
    1、Winform窗体控件布局

    2.源代码

    using System;
    using System.Threading;
    using System.Windows.Forms;

    namespace Windows.Forms.Timer
    {
    public partial class Form1 : Form
    {
    int num = 0;
    public Form1()
    {
    InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    timer1.Start();
    }

    private void button2_Click(object sender, EventArgs e)
    {
    timer1.Stop();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    label1.Text = (++num).ToString();
    Thread.Sleep(3000);
    }
    }
    }
    3.执行效果

    点击Start按钮后,界面假死3秒后,才可以移动窗体或点击控件按钮。

    二、System.Timers.Timer

    1. 用的不是Tick事件,而是Elapsed事件
    2. 和System.Windows.Forms.Timer一样,用Start和Stop方法
    3. AutoReset属性决定计时器是不是要发起一次事件然后停止,还是进入开始/等待的循环。System.Windows.Forms.Timer没有这个属性
    4. 设置对于UI控件的同步对象(synchronizing object),对控件的UI线程发起事件


    using System.Timers.Timer;
    在应用程序中生成定期事件。 精度相比Forms.Timer高,100ms间隔时,精度在10ms~20ms之间。(个人电脑测试)

    这个类更复杂,它包含了很多成员,使我们可以通过属性和方法来操作计时器。它还有一个叫做Elapsed的成员事件,每次时间到期就会引发这个事件。这个计时器可以运行在用户接口线程或工作者线程上。(引用自图书《C#图解教程(第四版)》439页)

    示例程序:
    1.源代码

    using System;
    using System.Diagnostics;
    using System.Timers;

    namespace Timers
    {

    class Program
    {

    static void Main(string[] args)
    {
    Stopwatch sw = new Stopwatch();
    sw.Start();
    Timer timer = new Timer();
    timer.Enabled = true;//设置是否执行Elapsed事件
    timer.Elapsed += new ElapsedEventHandler(printa);//绑定Elapsed事件
    timer.Interval =100;//设置时间间隔


    while (sw.ElapsedMilliseconds < 1000) //使定时器执行1s,之后停止
    {
    ;
    }
    timer.Stop();
    Console.ReadKey();
    }

    public static void printa(object sender, ElapsedEventArgs e)
    {
    Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + "执行Timer");
    }
    }

    }
    2.执行结果

    结果分析:100ms间隔时,精度在20ms以内。

    三、System.Threading.Timer
    using System.Threading.Timer;
    属于轻量级计时器,提供以指定的时间间隔执行方法的机制,无法继承此类。  精度相比Forms.Timer高,100ms间隔时,精度在10ms~20ms之间。(个人电脑测试)

    计时器在每次时间到期之后调用回调方法。构造函数结构如下(引用自图书《C#图解教程(第四版)》438页):

    示例程序:
    1.源代码

    //构建 Timer
    private static Timer timer = new Timer(TimerCallBack, null, 0, 5000);


    static void TimerCallBack(object state)
    {
    Console.WriteLine("{0} 执行一次", DateTime.Now);
    //执行完后,重新设置定时器下次执行时间.
    //timer.Change(nextTime.Subtract(DateTime.Now), Timeout.InfiniteTimeSpan);
    }

    using System;
    using System.Threading;
    using System.Diagnostics;

    namespace Timers
    {
    class Program
    {
    static Stopwatch sw = new Stopwatch();
    int TimesCalled = 0;

    void Display(object state)
    {
    Console.WriteLine("{0} {1},{2}", (string)state, ++TimesCalled,/*sw.ElapsedMilliseconds */DateTime.Now.ToString("HH:mm:ss.fff"));
    }

    static void Main()
    {
    Program p = new Program();

    sw.Start();
    Timer myTimer = new Timer(p.Display, "Processing timer event", 2000, 100);
    Console.WriteLine("Timer started.");

    Console.ReadLine();
    }
    }

    }
    2.执行结果

    结果分析:100ms间隔时,精度在20ms以内。此程序调试时,需要强行停止。

    结论:
    1、定时器中的执行任务比较耗时时,使用Timers.Timer和Threading.Timer更合适;

    2、多线程时,Timers.Timer和Threading.Timer比较,建议使用Timers.Timer。

    3、Forms.Timer适用在任务执行时间较短时使用。否则占用窗体UI线程,导致界面卡死等占用资源的情况。

    相关参考:

    1、https://blog.csdn.net/aoxuefeihu/article/details/7483227

    2、https://blog.csdn.net/lzp_k2/article/details/84102066

    https://blog.csdn.net/lzp_k2/article/details/84102066

  • 相关阅读:
    android有点纠结的小问题
    持久化应用程序实例的状态
    preference activity框架
    RISC与CISC比较
    C++ const用法
    虚析构函数
    best-case analysis in real-time system
    jitter
    C/C++中static,const,inline三种关键字详细总结
    #pragma warning(disable 4786)
  • 原文地址:https://www.cnblogs.com/micro-chen/p/12101297.html
Copyright © 2020-2023  润新知