背景
每种语言都有自己的定时器(Timer),很多人熟悉Javascript中的setInterval和setTimeout,在Javascript中为了实现平滑的动画一般采用setTimeout模拟setInterval,这是因为:setTimeout可以保证两次定时任务之间的时间间隔,而setInterval不行(小于设置的间隔时间)。C#中如何模拟setTimeout呢?
System.Timers.Timer
模拟setInterval
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Threading; namespace TimerTest
{
class Program
{
static void Main(string[] args)
{
var timer = new System.Timers.Timer();
timer.Elapsed += timer_Elapsed; Console.WriteLine(DateTime.Now.Second);
timer.Start(); Console.Read();
} static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Thread.Sleep();
Console.WriteLine(DateTime.Now.Second);
}
}
}
运行效果
分析
如果定时器任务执行的时间比较长,两次任务之间会有重叠,下面介绍如何避免这个问题。
模拟setTimeout
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Threading; namespace TimerTest
{
class Program
{
static void Main(string[] args)
{
var timer = new System.Timers.Timer();
timer.Elapsed += timer_Elapsed;
timer.AutoReset = false; Console.WriteLine(DateTime.Now.Second);
timer.Start(); Console.Read();
} static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Thread.Sleep();
Console.WriteLine(DateTime.Now.Second); (sender as System.Timers.Timer).Start();
}
}
}
运行效果
分析
这样就能保证定时任务的执行不会重叠了。
备注
while(true) + sleep 也可以做到,不知道微软的Timer内部是不是用sleep实现的。