System.Timers.Timer定时器的一些问题 做个笔记
最近在写一个控制台程序,需要用到定时器,因为没怎么写过控制台程序,所以后来确定了使用System.Timers.timer定时器,在使用的过程中,也就遇到了些问题,比如: 我在主程序中设定了一个定时器,设置了该定时器的一些参数(如:间隔时间,启动定时器,定时器的 Elapsed事件),然后在使用的时候,会发现当 Elapsed事件的执行时间超过了该定时器的间隔的话,会产生一些不好的后果,又或者当我们在该定时器的 Elapsed事件里面在设定一个定时器,当Elapsed事件的执行时间超过主定时器的间隔,也会产生不好的效果,这样的话我们怎么来解决呢?然我们用代码来看看。
首先我们来看下当 Elapsed事件的执行时间大于定时器的间隔的话,会发生怎样的事情。
using System; using System.Collections.Generic; using System.Text; using System.Timers; namespace ConsoleTesk { class Program { static Timer timerOne = new Timer(); static int num = 0; static int i = 0; static void Main(string[] args) { timerOne.Interval = 1000 * 1;//设定定时器执行间隔为1s timerOne.Elapsed += new ElapsedEventHandler(timerOne_Elapsed); timerOne.Enabled = true; string readLine; do { readLine = Console.ReadLine(); } while (readLine != null && readLine != "exit"); } private static void timerOne_Elapsed(object source, ElapsedEventArgs e) { i++; if (i <= 5) { Method(); } } private static void Method() { Console.WriteLine(DateTime.Now.ToString()); Timer timerSecond = new Timer(); timerSecond.Interval = 1000 * 2;//设定定时器执行间隔为2s timerSecond.Elapsed += new ElapsedEventHandler(timerSecond_Elapsed); timerSecond.Enabled = true; } private static void timerSecond_Elapsed(object source, ElapsedEventArgs e) { Timer s = (Timer)source; Console.WriteLine("123456"); s.Enabled = false; s.Dispose(); } } }
编译后运行得到的结果是:
我们能看到当Elapsed事件的执行时间大于定时器的间隔的话,很显然得到的结果不是我们想要的,我找到的解释是:
Elapsed 事件在 ThreadPool 线程上引发。如果 Elapsed 事件的处理时间比 Interval 长,在另一个 ThreadPool 线程中将会再次引发此事件。因此,事件处理程序应当是可重入的。那么我们怎样才能达到我们想要的效果呢?修正后程序为:
using System; using System.Collections.Generic; using System.Text; using System.Timers; namespace ConsoleTesk { class Program { static Timer timerOne = new Timer(); static object lockNum = new object(); static object lockNum2 = new object(); static int num = 0; static int i = 0; static void Main(string[] args) { timerOne.Interval = 1000 * 1; //设定定时器的间隔为1s timerOne.Elapsed += new ElapsedEventHandler(timerOne_Elapsed); timerOne.Enabled = true; string readLine; do { readLine = Console.ReadLine(); } while (readLine != null && readLine != "exit"); } private static void timerOne_Elapsed(object source, ElapsedEventArgs e) { i++; if (i <= 5) { Method(); } } private static void Method() { timerOne.Enabled = false;//设置第一个定时器为停止 Console.WriteLine(DateTime.Now.ToString()); Timer timerSecond = new Timer(); timerSecond.Interval = 1000 * 4;//设定定时器的间隔为4s timerSecond.Elapsed += new ElapsedEventHandler(timerSecond_Elapsed); timerSecond.Enabled = true; } private static void timerSecond_Elapsed(object source, ElapsedEventArgs e) { num++; Timer s = (Timer)source; Console.WriteLine("123456"); if (num > 2) { s.Enabled = false; s.Dispose(); timerOne.Enabled = true;//当第二个定时器执行完毕后启动后启动第一个定时器 num = 0; } } } }
得到的结果是:
结果完全符合我们的要求。