C#的四种Timer介绍
一.Timer的几个类别
1.System.Threading.Timer
2.System.Timers.Timer
3.System.Windows.Forms.Timer
4.System.Windows.Threading.DispatcherTimer
二.System.Threading.Timer
他的源代码里是这样写的:
public sealed class Timer : MarshalByRefObject, IDisposable { // Fields private TimerHolder m_timer; private const uint MAX_SUPPORTED_TIMEOUT = 0xfffffffe; // Methods [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical] public Timer(TimerCallback callback); [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical, __DynamicallyInvokable] public Timer(TimerCallback callback, object state, int dueTime, int period); [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical] public Timer(TimerCallback callback, object state, long dueTime, long period); [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical, __DynamicallyInvokable] public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period); [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false), SecuritySafeCritical] public Timer(TimerCallback callback, object state, uint dueTime, uint period); [__DynamicallyInvokable] public bool Change(int dueTime, int period); public bool Change(long dueTime, long period); [__DynamicallyInvokable] public bool Change(TimeSpan dueTime, TimeSpan period); [CLSCompliant(false)] public bool Change(uint dueTime, uint period); [__DynamicallyInvokable] public void Dispose(); public bool Dispose(WaitHandle notifyObject); internal void KeepRootedWhileScheduled(); [SecurityCritical] internal static void Pause(); [SecurityCritical] internal static void Resume(); [SecurityCritical] private void TimerSetup(TimerCallback callback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark); }
主要有四个参数。
CallBack,一个返回值为void,参数为object的委托,也是计时器执行的方法。
state,计时器执行方法的的参数。
dueTime,调用 callback 之前延迟的时间量(以毫秒为单位)。
period,调用 callback 的时间间隔。
例:System.Threading.Timer tm=new System.Threading.Timer(Tick_tick,null,10000,20000);//10秒后开始计时,20秒后调用Tick_tick事件。
特点:多线程计时器,精确,而且可扩展性强。
三.System.Timers.Timer
在Reflector里反射出来的源代码:
public Timer(); public Timer(double interval); public void BeginInit(); public void Close(); protected override void Dispose(bool disposing); public void EndInit(); [SuppressUnmanagedCodeSecurity, DllImport("kernel32.dll")] internal static extern void GetSystemTimeAsFileTime(ref FILE_TIME lpSystemTimeAsFileTime); private void MyTimerCallback(object state); public void Start(); public void Stop(); private void UpdateTimer(); // Properties [Category("Behavior"), TimersDescription("TimerAutoReset"), DefaultValue(true)] public bool AutoReset { get; set; } [Category("Behavior"), TimersDescription("TimerEnabled"), DefaultValue(false)] public bool Enabled { get; set; } [Category("Behavior"), TimersDescription("TimerInterval"), DefaultValue((double) 100.0), SettingsBindable(true)] public double Interval { get; set; } public override ISite Site { get; set; } [Browsable(false), DefaultValue((string) null), TimersDescription("TimerSynchronizingObject")] public ISynchronizeInvoke SynchronizingObject { get; set; }
BeginInit(),初始化。
AutoReset,只执行一次或重复执行。
enabled,获取或设置一个值,该值指示 Timer 是否应引发 Elapsed 事件。
Interval,相应间隔时间。
Elapsed绑定响应事件。
例:
public MainWindow() { InitializeComponent(); System.Timers.Timer timer = new System.Timers.Timer(); timer.AutoReset = true; timer.Enabled = true; timer.Interval=10000; timer.Elapsed += timer_Elapsed; timer.Start(); } void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { MessageBox.Show("响应事件"); }
特点:相对System.Threading.Timer进行了简单包装。多线程计时器
实现了Component,所以可以在设计器显示。代替Change方法的一个Interval属性代替callback委托的一个Elapsed事件启动和停止timer的Enabled属性,默认是false。
为了避免Enabled造成混乱,提供了Start和Stop方法。是否在每次指定的间隔结束时引发Elapsed时间,还是仅间隔第一次结束后运行的AutoReset属性。
四.差异
(1)上述两个Timer都是多线程计时器。Timer每到间隔时间后就会激发响应事件,因此要申请线程来执行对应的响应函数,Timer将获取线程的工作都交给了线程池来管理,
每到一定的时间后它就去告诉线程池:“我现在激发了个事件要运行对应的响应函数,麻烦你给我向操作系统要个线程,申请交给你了,线程分配下来了你就运行我给你的响应函数,
没分配下来先让响应函数在这儿排队(操作系统线程等待队列)”,消息已经传递给线程池了,Timer也就不管了,因为它还有其他的事要做(每隔一段时间它又要激发事件),
至于提交的请求什么时候能够得到满足,要看线程池当前的状态,如果线程满了就排队,在有空线程时就会响应函数。否则就直接响应。
(2)而下述两个是单线程计时器,其工作机制也和上面不同。计时器使用消息循环机制来取代线程池产生消息的机制。
这意味着Tick事件总是在创建timer的那个线程上执行,同时也意味着如果上一个Tick消息还未被处理,即使时间超过了间隔时间,在消息循环中也只存在一个Tick消息。
下面是它们的优点:
你可以忘记线程安全。一个Tick事件在前一个Tick事件被处理完毕前不会被触发。你可以直接在Tick事件处理代码中更新控件,不需要调用Control.Invoke或Dispatcher.Invoke.
五.System.Windows.Forms.Timer
专门适用于WindowForm,单线程使用。由于单线程计时器基于Windows消息循环,应用程序会同步的处理计时器的消息。UI界面会相对响应速度很慢。
WinForm不常用,就不写了。
六.System.Windows.Threading.DispatcherTimer
Reflector的源代码方法
public DispatcherTimer(); public DispatcherTimer(DispatcherPriority priority); public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher); public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher); private object FireTick(object unused); private void Initialize(Dispatcher dispatcher, DispatcherPriority priority, TimeSpan interval); internal void Promote(); private void Restart(); public void Start(); public void Stop(); // Properties public Dispatcher Dispatcher { get; } public TimeSpan Interval { get; set; } public bool IsEnabled { get; set; } public object Tag { get; set; } }
类似于System.Threading.Timer
例:
public MainWindow() { InitializeComponent(); Timer.Interval = TimeSpan.FromSeconds(1000); Timer.IsEnabled = true; Timer.Tick += Timer_Tick; } void Timer_Tick(object sender, EventArgs e) { throw new NotImplementedException(); } private DispatcherTimer Timer;