.Net Framework下Timer类之对比
来源:互联网 发布:不列颠空战知乎 编辑:程序博客网 时间:2024/06/01 07:27
原文:http://msdn.microsoft.com/en-us/magazine/cc164015.aspx
原作者:Alex Calvo,is a Microsoft Certified Solutions Developer for .NET. When he's not reading, coding, or meditating, he's playing guitar. You can reach Alex at acalvo@hotmail.com.
注意: 有删节,仅译出其要点而已,也有自己添加的理解。
概要:
.NET Framework Class Library提供了三种不同的时钟类:System.Windows.Forms.Timer, System.Timers.Timer and System.Threading.Timer.各有不同的用武之地,本文旨在介绍其用法。
内容:
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
Dealing with Timer Event Reentrance
Conclusion
.NET Framework Class Library提供了三种不同的时钟类:System.Windows.Forms.Timer, System.Timers.Timer and System.Threading.Timer.各有不同的用武之地,本文旨在介绍其用法。
内容:
System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
Dealing with Timer Event Reentrance
Conclusion
1)System.Windows.Forms.Timer
该类的最大特点是其与Winforms App同步,也就是说它的Tick events与UI在同一个线程执行。如果在响应函数执行耗时较多的话,则会出现UI无响应的情况。由此可见该类比较适用一些比较简单的情况。
原文链接中给出了一些演示示例,供读者来理解该类:
System.Windows.Forms.Timer Started @ 4:09:28 PM--> Timer Event 1 @ 4:09:29 PM on Thread: UIThread--> Timer Event 2 @ 4:09:30 PM on Thread: UIThread--> Timer Event 3 @ 4:09:31 PM on Thread: UIThreadSleeping for 5000 ms...--> Timer Event 4 @ 4:09:36 PM on Thread: UIThreadSystem.Windows.Forms.Timer Stopped @ 4:09:37 PM
从上面代码可以看出,在其响应函数中休眠5000ms,这五秒钟的Timer Event就失效了。足见该Timer Event是在UI线程中执行的。此外要注意的是,尽管该类的Interval 最小可以为1ms,但是官方的文档说明该类大概只能精确到55ms.
下面代码是使用System.Windows.Forms.Timer class 示例:
System.Windows.Forms.Timer tmrWindowsFormsTimer = new System.Windows.Forms.Timer();tmrWindowsFormsTimer.Interval = 1000;tmrWindowsFormsTimer.Tick += new EventHandler(tmrWindowsFormsTimer_Tick);tmrWindowsFormsTimer.Start();•••private void tmrWindowsFormsTimer_Tick(object sender, System.EventArgs e) { //Do something on the UI thread...}
2)System.Timers.Timer
.Net Framework称该类是专为多线程环境而设计,且该类的对象是thread-safe的。不同于System.Windows.Forms.Timer,该类的Timer Event是在worker thread(来自线程池)中执行的,这就带来一个问题,如果你的响应函数中涉及到UI操作的话,那么一定要回调到UI线程执行。不过,System.Timers.Timer class提供了一种简单的方式来克服这种麻烦,它采用了“SynchronizingObject ”属性,若将UI forms 赋值于该属性,则SynchronizingObject.Begin.Invoke可让Timer Event在UI线程执行。考虑到UI的responsiveness,我觉得这个属性有些鸡肋。
演示代码:
使用示例:
3)System.Threading.Timer
该类可以说是三个类中最灵活的一个,但是其对象本身却并非thread-safe的。此外,其使用方式也与前二者不同: 演示代码:
4)Timer event重复进入问题
对于System.Timers.Timer class和System.Threading.Timer,其timer event异步执行的,还有一个问题需要注意。如果响应函数执行时间超过了Interval值,那么响应函数会被重复进入,那么在这里就特别需要注意变量的同步了。如果读者不想反复进入呢,那么可以参考如下示例:
5)总结
Timer Classes in the .NET FCL
System.Windows.FormsSystem.TimersSystem.ThreadingTimer event 所在线程UI threadUI or worker threadWorker thread对象是否thread safe?NoYesNo是否需要Windows Forms?YesNoNoTimer event 是否支持状态变量?NoNoYes初始timer event是否可被延迟?NoNoYesClass 是否支持继承?YesYesNo
相关文章:
Windows Forms: Give Your .NET-Based Application a Fast and Responsive UI with Multiple Threads
背景信息:
Programming the Thread Pool in the .NET Framework: Using Timers
.NET Framework Class Library
演示代码:
System.Timers.Timer Started @ 5:15:01 PM--> Timer Event 1 @ 5:15:02 PM on Thread: WorkerThread--> Timer Event 2 @ 5:15:03 PM on Thread: WorkerThread--> Timer Event 3 @ 5:15:04 PM on Thread: WorkerThreadSleeping for 5000 ms...--> Timer Event 4 @ 5:15:05 PM on Thread: WorkerThread--> Timer Event 5 @ 5:15:06 PM on Thread: WorkerThread--> Timer Event 6 @ 5:15:07 PM on Thread: WorkerThread--> Timer Event 7 @ 5:15:08 PM on Thread: WorkerThread--> Timer Event 8 @ 5:15:09 PM on Thread: WorkerThreadSystem.Timers.Timer Stopped @ 5:15:10 PM
这里有个问题需要注意,由于timer event是在独立线程中执行的,那么有可能用户已经调用stop函数了,仍会产生timer event事件。ElapsedEventArgs 中包含了一个“SignalTime ”属性,表示已经过去的时间,用户可以将这个时间与stop函数的调用时间相比,以决定是否继续执行响应函数。笔者在这里就遇到一个类似的问题,在窗体函数已经销毁后,仍在timer event响应函数中调用Invoke函数,导致了异常,通过该属性则可避免类似情况。System.Timers.Timer tmrTimersTimer = new System.Timers.Timer();tmrTimersTimer.Interval = 1000;tmrTimersTimer.Elapsed += new ElapsedEventHandler(tmrTimersTimer_Elapsed);tmrTimersTimer.SynchronizingObject = this; //Synchronize with //the current form...tmrTimersTimer.Start();•••private void tmrTimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // Do something on the UI thread (same thread the form was // created on)... // If we didn't set SynchronizingObject we would be on a // worker thread...}
3)System.Threading.Timer
该类可以说是三个类中最灵活的一个,但是其对象本身却并非thread-safe的。此外,其使用方式也与前二者不同:
public Timer(TimerCallback callback, object state, long dueTime, long period);public Timer(TimerCallback callback, object state, UInt32 dueTime, UInt32 period);public Timer(TimerCallback callback, object state, int dueTime, int period);public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period);
与 System.Timers.Timer class相比较, 该类并没有“SynchronizingObject ”这个属性,也就是说,若在响应函数中涉及UI操作,则需用户自己调用Invoke或者BeginInvoke。System.Threading.Timer Started @ 7:17:11 AM--> Timer Event 1 @ 7:17:12 AM on Thread: WorkerThread--> Timer Event 2 @ 7:17:13 AM on Thread: WorkerThread--> Timer Event 3 @ 7:17:14 AM on Thread: WorkerThreadSleeping for 5000 ms...--> Timer Event 4 @ 7:17:15 AM on Thread: WorkerThread--> Timer Event 5 @ 7:17:16 AM on Thread: WorkerThread--> Timer Event 6 @ 7:17:17 AM on Thread: WorkerThread--> Timer Event 7 @ 7:17:18 AM on Thread: WorkerThread--> Timer Event 8 @ 7:17:19 AM on Thread: WorkerThreadSystem.Threading.Timer Stopped @ 7:17:20 AM
4)Timer event重复进入问题
对于System.Timers.Timer class和System.Threading.Timer,其timer event异步执行的,还有一个问题需要注意。如果响应函数执行时间超过了Interval值,那么响应函数会被重复进入,那么在这里就特别需要注意变量的同步了。如果读者不想反复进入呢,那么可以参考如下示例:
在响应函数中操作其Enabled属性。private void tmrTimersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { tmrTimersTimer.Enabled = false; System.Threading.Interlocked.Increment(ref tickCounter); Thread.Sleep(5000); MessageBox.Show(tickCounter.ToString()); tmrTimersTimer.Enabled = true;}
5)总结
System.Windows.FormsSystem.TimersSystem.ThreadingTimer event 所在线程UI threadUI or worker threadWorker thread对象是否thread safe?NoYesNo是否需要Windows Forms?YesNoNoTimer event 是否支持状态变量?NoNoYes初始timer event是否可被延迟?NoNoYesClass 是否支持继承?YesYesNo
相关文章:
Windows Forms: Give Your .NET-Based Application a Fast and Responsive UI with Multiple Threads
背景信息:
Programming the Thread Pool in the .NET Framework: Using Timers
.NET Framework Class Library
- .Net Framework下Timer类之对比
- .NET Mocking Framework对比
- .NET Framework中的三个Timer类型
- .Net Compact Framework 中使用 Timer
- windows ce下Win32,MFC和.NET Compact FrameWork的对比
- 定时器:.NET Framework类库中的Timer类比较(翻译)
- Comparing the Timer Classes in the .NET Framework Class Library
- [.Net码农]WPF 下的Timer控件
- java之Timer类
- .Net 多线程之Timer的应用
- .Net FrameWork 4.0之WorkFlow
- .Net平台下的第三方Excel类库对比
- linux下之定时器timer实例
- .Net FrameWork常用类
- .NET Compact Framework下的进程间通信之Windows Message
- .NET Compact Framework下的进程间通信之MSMQ开发
- ADO.NET Entity Framework 4.3 之 Code First 下自动更新数据库结构(Automatic Migrations)
- ASP.NET企业开发框架IsLine FrameWork系列之六--DataProvider 数据访问(下)
- Render和visible----------ADF Faces入门(文档阅读)
- 冒泡排序算法
- Java 静态扫描工具:findbugs eclipse 插件 的介绍、安装、使用
- dedecms自定义字段的添加及如何实现在栏目页首页的调用
- ADF 中加入多个face-config.xml 文件
- .Net Framework下Timer类之对比
- 博客搬家,顺带来些学生时代乱七八糟写的东东
- SQL注入语句 (很全)
- 聚集索引和非聚集索引的区别:
- gridview导入到excel
- hudson乱码
- 幂等性 个人理解及应用
- mysql行级锁测试
- hudson提取公司名