C#.Net 定时器

如果需要定期重复执行一些方法,最容易的方式就是使用定时器。相比以下方式,定时器既方便使用又能高效地利用内存和资源。

new Thread(delegate ()
{
    while (enabled)
    {
        DoSomeAction();
        Thread.Sleep(TimeSpan.FromHours(24));
    }
}).Start();

上述方式不仅永久占用了线程资源,而且如果不进行额外的编码,DoSomeAction每天的执行时间都会向后推延,定时器则解决了这些问题。
.NET Core提供了四种定时器,其中的两种定时器是通用多线程定时器

  • System.Threading.Timer
  • System.Timers.Timer

另外两种则是特殊用途的单线程定时器:

  • System.Windows.Forms.Timer(Windows Forms应用的定时器)
  • System.Windows.Threading.DispatcherTimer(WPF的定时器)

多线程定时器更加强大,定时精确,使用灵活;对于定期更新Windows Forms或WPF界面元素的简单任务来说,单线程定时器更加安全方便。

多线程定时器

System.Threading.Timer是最简单的多线程定时器:它只有一个构造器和两个方法。
在下面的例子中,定时器会在第一个五秒钟结束后调用Tick方法,并输出“tick...”。而后每秒钟调用一次Tick方法,直至用户按下回车键:

 static void Tick(object data)
 {
     Console.WriteLine(data);
 }
 static void Main(string[] args)
 {
     Timer tmr = new Timer(Tick, "tick...", 5000, 1000);
     Console.ReadLine();
     tmr.Dispose();

     Console.ReadKey();
 }

在创建定时器之后仍然可以调用Change方法来修改定时器的定时间隔。如果希望定时器只触发一次,则可以用Timeout.Infinite作为构造器的最后一个参数。

.NET Core在System.Timers命名空间中提供了另外一个同名定时器类。它简单包装了System.Threading.Timer,在相同底层引擎的基础上提供了额外的易用性。

static void tmr_Elapsed(object sender, EventArgs e)
{
    Console.WriteLine("Tick");
}
static void Main(string[] args)
{
    var tmr = new System.Timers.Timer(); // 不需要任何参数
    tmr.Interval = 500;
    tmr.Elapsed += tmr_Elapsed;    // 使用事件而不是委托
    tmr.Start();                   // 开始
    Console.ReadLine();
    tmr.Stop();                    // 停止
    Console.ReadLine();
    tmr.Start();                   // 重启
    Console.ReadLine();
    tmr.Dispose();                 // 销毁

    Console.ReadKey();
}

多线程定时器会使用线程池来用有限的线程为多个定时器提供服务。因此,回调方法或者Elapsed事件每一次都可能在不同的线程上触发。此外,Elapsed事件几乎能够保证触发的时效性而不管前一次Elapsed事件是否执行完毕。因此,不论是回调委托还是事件处理器必须是线程安全的。

单线程定时器

.NET Core专门为WPF和Windows Forms应用程序提供了不需要考虑线程安全性的定时器

这两种定时器的成员都和System.Timers.Timer的成员非常相似:Interval属性、Start和Stop方法(Tick事件和Elapsed事件是等价的);其使用方法也非常相似。但是它们内部的工作原理是不同的。

WPF与Windows Forms定时器并不会在线程池线程上触发定时器事件;而是将事件发送到WPF和Windows Forms消息循环中。这意味着Tick事件总会在创建定时器的线程上触发。而在一般应用程序中,这个线程也是用来管理所有用户界面元素和控件的线程。

WPF和Windows Forms定时器适用于执行细小的工作,通常用于更新UI的某一个部分(例如,显示时钟或者显示倒计时)。

posted @ 2022-09-01 11:11  一纸年华  阅读(1807)  评论(0编辑  收藏  举报