C# Timer 定时器
Timer简单介绍
构造函数
通过ILSpy反编译可以看到Timer的内部代码。
Timer 的默认构造函数里赋了初值,所以当我们初始化Timer的时候,已经有了默认值。
Timer 的带参数的构造函数会重新给 interval(获取或设置引发 Elapsed 事件的间隔,以毫秒为单位。)赋值。
Elapsed事件(达到间隔时发生)
匿名函数传递
System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 10); //实例化,设置时间间隔为十分钟,此处参数单位为毫秒。//匿名函数传递 t.Elapsed += (s, e) => { print(DateTime.Now); };
非匿名函数传递
System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 10); //实例化,设置时间间隔为十分钟,此处参数单位为毫秒。 t.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => print(DateTime.Now));//非匿名函数传递
下面是写在 Global.asax.cs 里例子,项目启动的时候会执行:
//第一个访问网站的用户会触发该方法。 protected void Application_Start() { DateTime dt = DateTime.Now;
System.Timers.Timer t = new System.Timers.Timer(1000 * 60 * 10); //实例化,设置时间间隔为十分钟,此处参数单位为毫秒 t.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => print(dt)); t.AutoReset = true; //每到指定时间Elapsed事件是触发一次(false),一直触发(true) t.Enabled = true; //是否触发Elapsed事件 t.Start(); }
定时器
现在我们有个需求,需要每天12点来触发 print 方法,那么我们需要利用 Timer 写一个定时器。通过更改 Interval 属性的数值,来调整触发方法的时间。
下面是demo
private static readonly System.Timers.Timer Timer = new System.Timers.Timer(); //初始化。 private static DateTime dt = new DateTime(); //固定时间。 /// <summary> /// 程序入口(自行调用) /// </summary> /// <param name="timing">定时时间(格式:年月日时分秒)</param> public void Init() { dt = DateTime.Now; SetInterval(); Timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => SetInterval()); } /// <summary> /// 定时器 /// </summary> /// <param name="timing">定时时间(格式:年月日时分秒)</param> private void SetInterval() { Timer.Stop(); var now = DateTime.Now; if (now >= dt)//如果当前时间>=定时时间 { //定时结束之后,你要执行的代码 print(now); //---------------------------------------------------------- //此处可修改dt。更改需求。 //---------------------------------------------------------- dt = DateTime.Now.Date.AddDays(1).AddHours(12); //重新计算定时时间,第二天12点再执行。 //dt = DateTime.Now.AddMinutes(0.1);//重新计算定时时间,每分钟执行一次。 SetInterval(); } else//如果当前时间<定时时间 { Timer.Interval = dt.Subtract(now).TotalMilliseconds;//重新计算定时时间,按毫秒计算。 Timer.Start(); } } /// <summary> /// 测试输出 /// </summary> public void print(DateTime dt) { num++; Console.WriteLine("执行第{0}次,时间:{1}", num, dt); }
效果:
现在需求变更为每天11点到下午17点的时候触发,间隔1分钟。
下面是demo
private static readonly System.Timers.Timer Timer = new System.Timers.Timer(); //初始化。 private static DateTime dtStar = new DateTime(); //时间段--开始时间。 private static DateTime dtEnd = new DateTime(); //时间段--结束时间。 private static int intervalTime = 10;//间隔时间(分钟)。 /// <summary> /// 程序入口(自行调用) /// </summary> /// <param name="timing">定时时间(格式:年月日时分秒)</param> public void Init() { dtStar = DateTime.Now.Date.AddDays(0).AddHours(11);//今天11点。 dtEnd = DateTime.Now.Date.AddDays(0).AddHours(17);//今天17点。 intervalTime = 1;//每1分钟执行一次。 SetInterval(); Timer.Elapsed += new System.Timers.ElapsedEventHandler((s, e) => SetInterval()); } /// <summary> /// 定时器(间断) /// </summary> /// <param name="timing">起始时间</param> private void SetInterval() { Timer.Stop(); var now = DateTime.Now; if (now.Hour >= dtStar.Hour && now.Date == dtStar.Date)//达到开始时间,并且是今天 { if (dtEnd.Subtract(now).TotalMinutes >= intervalTime)//小于结束时间 { print(now);//打印 //---------------------------------------------------------- //此处可修改dtStar,dtEnd,intervalTime,三个参数。更改需求。 //---------------------------------------------------------- Timer.Interval = now.AddMinutes(intervalTime).Subtract(now).TotalMilliseconds; Timer.Start(); } else { //---------------------------------------------------------- //此处可修改dtStar,dtEnd,intervalTime,三个参数。更改需求。 //---------------------------------------------------------- dtStar = DateTime.Now.Date.AddDays(1).AddHours(11);//第二天11点。 dtEnd = DateTime.Now.Date.AddDays(1).AddHours(17);//第二天17点。 intervalTime = 2;//每2分钟执行一次。 Timer.Interval = dtStar.Subtract(now).TotalMilliseconds; Timer.Start(); } } else//如果 定时时间>当前时间 { Timer.Interval = dtStar.Subtract(now).TotalMilliseconds;//重新计算定时时间,按毫秒计算。 Timer.Start(); } } /// <summary> /// 测试输出 /// </summary> public void print(DateTime dt) { num++; Console.WriteLine("执行第{0}次,时间:{1}", num, dt); }