FCL中提供了三个定时器,而对于大多数程序员来说,他们不太清楚这三个定时器之间的区别。
下面我们对这三个定时器进行分析:
System.Threading的Timer类,这个定时器使我们最常用的定时器,当我们希望在另一个线程上定时执行后台任务时,这个定时器是最好的选择。
System.Windows.Forms的Timer类 构建一个该类的实例可以告诉Windows将定时器与调用线程关联。随着定时器的触发,Windows将一个定时器消息(WM_TIMER)插入到线程的消息队列中。调用线程必须执行一个消息泵(message pump),从而提取消息,并将他们分派到期望的回调方法中。注意,所有这些工作都是由一个线程完成的----设置定时器的线程保证是执行回调方法的线程。这同样意味着我们的定时器方法不能被多个线程同时执行。
System.Timers的Timer类 该定时器基本上是对System.Threading的Timer类的包装,当定时器时间到期后,将导致CLR将事件加入线程池的队列中。Component类允许将这些定时器对象放置在Microsoft Visual Studio设计界面上。另外,System.Timers.Timer类的成员也有点不同。这个类在数年前就被添加到FCL中了,而那时Microsoft仍然在对线程处理和定时器材质进行分类。这个类或许被移除,以便于每个人都可以使用System.Threading的Timer类。实际上,我们从来不使用System.Timer.Timer类,而且我还劝大家不要使用这个类,除非大家这的希望在设计界面上使用定时器。
下面是一个System.Threading的Timer类例子,这个类是我们经常使用的:
using System; using System.Threading; namespace TestTimer { public class Program { public static void Main(string[] args) { Console.WriteLine("主线程:正在启动Timer"); //ComputeBoundOp是被执行的函数 Timer t = new Timer(ComputeBoundOp, 5, 0, 2000); Console.WriteLine("主线程: 正在工作。。。"); Thread.Sleep(10000); //模拟工作(10秒钟) t.Dispose(); //取消定时器 } /// <summary> /// 该方法的签名必须与TimerCallback委托类型匹配 /// </summary> /// <param name="state"></param> private static void ComputeBoundOp(Object state) { //该方法由线程池中的线程执行 Console.WriteLine("在ComputeBoundOp中: state={0}", state); Thread.Sleep(1000); //模拟其他工作(1秒钟) //在这个方法返回后,线程就回到线程池中,然后等待执行另一个任务 } } }
当Timer对象被执行垃圾收集时,CLR就会取消定时器,以便定时器不再继续触发,因此,使用Timer对象时,一定要确保一个变量来引用Timer对象,从而保持Timer对象继续存活,否则回调方法就不会再被调用。
Timer t = new Timer(ComputeBoundOp, 5, 0, 2000);这段代码中,ComputeBoundOp是线程回调的方法,5是构造器的state参数,它允许我们将状态数据传递给回调方法,如果没有状态数据可传递,可以传递null。0是dueTime参数,dueTime参数可以告诉CLR在第一次调用回调方法时需要等待多少毫秒。在这里设置为0,表示希望回调方法立即被调用。2000是period参数,它表示回调方法执行的间隔时间,这里我们设置的是2000毫秒.
更多原创内容,可以到我的小站(www.shuonar.com)进行阅读,欢迎拍砖。