如果你需要使用规律的时间间隔重复执行一些方法,最简单的方式是使用定时器(timer)。与下边的例子相比,定时器可以便捷、高效地使用内存和资源:
new Thread (delegate() { while (enabled) { DoSomeAction(); Thread.Sleep (TimeSpan.FromHours (24)); } }).Start();
这不仅仅会永久占用一个线程,而且如果没有额外的代码,DoSomeAction每天都会发生在更晚的时间。定时器解决了这些问题。
.NET Framework 提供了 4 种定时器。下边两个类是通用的多线程定时器:
(1)System.Threading.Timer
(2)System.Timers.Timer
另外两个是专用的单线程定时器:
(3)System.Windows.Forms.Timer (Windows Forms 的定时器)
(4)System.Windows.Threading.DispatcherTimer (WPF 的定时器)
多线程定时器更加强大、精确并且更加灵活,而单线程定时器对于一些简单的更新 Windows Forms 和 WPF 控件的任务来说是安全的,并且更加便捷。
1.多线程定时器Permalink
System.Threading.Timer是最简单的多线程定时器:它仅仅有一个构造方法和两个普通方法(取悦于极简主义者,还有本书作者!)。在接下来的例子中,一个定时器在 5 秒钟之后调用Tick方法来打印 “ tick… “,之后每秒打印一次直到用户按下回车键:
using System;using System.Threading;class Program{ static void Main() { // 首次间隔 5000ms,之后间隔 1000ms Timer tmr = new Timer (Tick, "tick...", 5000, 1000); Console.ReadLine(); tmr.Dispose(); // 停止定时器并执行清理工作 } static void Tick (object data) { // 这里运行在一个线程池线程上 Console.WriteLine (data); // 打印 "tick..." }}
之后可以通过调用Change方法来改变定时器的时间间隔。如果你希望定时器只触发一次,可以指定Timeout.Infinite作为构造方法的最后一个参数。
.NET Framework 在System.Timers命名空间下提供了另一个名字相同的定时器类。它只是封装了 System.Threading.Timer,并在使用完全相同的底层引擎的前提下提供额外的便利。下面是增加功能的简介:
(1)实现了Component,允许用于 Visual Studio 的设计器中。
(2)Interval属性代替了Change方法。
(3)Elapsed事件代替了回调委托。
(4)Enabled属性用于开始或停止定时器(默认值是false)。
(5)Start和Stop方法,避免对Enabled属性感到困惑。
(6)AutoReset标识来指定是否为可重复的事件(默认为true)。
SynchronizingObject属性提供Invoke和BeginInvoke方法,用于在 WPF 和 Windows Forms 控件上安全调用方法。
这有个例子:
using System;using System.Timers; // 命名空间是 Timers 而不是 Threadingclass SystemTimer{ static void Main() { Timer tmr = new Timer(); // 无需任何参数 tmr.Interval = 500; tmr.Elapsed += tmr_Elapsed; // 使用事件代替委托 tmr.Start(); // 开启定时器 Console.ReadLine(); tmr.Stop(); // 停止定时器 Console.ReadLine(); tmr.Start(); // 重启定时器 Console.ReadLine(); tmr.Dispose(); // 永久停止定时器 } static void tmr_Elapsed (object sender, EventArgs e) { Console.WriteLine ("Tick"); }}
新闻热点
疑难解答
图片精选