System.Timers.Timer与System.Threading.Timer
最近我一直在检查一些可能的定时器,并且Threading.Timer和Timers.Timer是那些看起来需要的东西(因为它们支持线程池)。
我在做一个游戏,我计划使用所有types的事件,以不同的时间间隔等等。
哪个会是最好的?
本文提供了一个相当全面的解释:
“ 比较.NET Framework类库中的计时器类 ” – 也可作为.chm文件使用
具体区别似乎是System.Timers.Timer
面向multithreading应用程序,因此通过其SynchronizationObject
属性是线程安全的,而System.Threading.Timer
具有讽刺意味的是不是线程安全的开箱即用。
我不相信这两者之间是有区别的,因为它与你的间隔有多小有关。
System.Threading.Timer
是一个普通的计时器。 它会callback一个线程池线程(来自工作池)。
System.Timers.Timer
是一个System.ComponentModel.Component
,它封装了一个System.Threading.Timer
,并提供了一些用于在特定线程上调度的附加function。
System.Windows.Forms.Timer
改为包装本地消息HWND,并使用Window Timers在该HWNDs消息循环中引发事件。
如果你的应用程序没有用户界面,并且你想要最轻量级和通用的.Net定时器,(因为你很高兴搞清楚你自己的线程/调度),那么System.Threading.Timer
是一样的好该框架。
我不完全清楚System.Threading.Timer
所谓的“不是线程安全”的问题。 也许这个问题和这个问题一样: System.Timers.Timer与System.Threading.Timer的线程安全性 ,也许每个人都意味着:
-
当你使用定时器时很容易写出竞争条件。 例如看到这个问题: Timer(System.Threading)线程安全
-
定时器通知的重新进入,在定时器事件可以触发的地方,并在完成处理第一个事件之前再次打电话给您。 例如看到这个问题: 使用System.Threading.Timer和Monitor进行线程安全的执行
在他的书“ CLR Via C# ”中, Jeff Ritcher不鼓励使用System.Timers.Timer
,这个定时器是从System.ComponentModel.Component
派生的,允许它在Visual Studio的devise表面中使用。 所以只有在devise表面上需要计时器时才有用。
他更喜欢在线程池线程上使用System.Threading.Timer
作为后台任务。
System.Timers.Timer
似乎被.NET Core和ASP.NET Core弃用。 所以在未来的应用程序中尝试使用System.Threading.Timer
。
编辑:好的,让我更加精确:
随着新的.NET核心框架,微软停止了.NET框架的一些技术。 要理解:.NET Core是一个全新的框架 – 重写,跨平台等。我不想在这里深入细节 – 请阅读.NET博客 。
在博客上有一篇很好的文章,向.NET Core介绍,这也解释了你可能遇到的困难。 其中的一部分是使用.NET可移植性分析器Visual Studio加载项,并修复您得到的错误。
对于System.Timers.Timer
类,它表示支持.NET Framework V4.6.2,但是.NET Core V5.0和.NETPlatform Version V5.0不支持。 build议的更改: Use System.Threading.Timer
。
所以,那看起来我的System.Timers.Timer
已经消失的.NET核心。
PS:但是它可能会回来 – 微软宣布他们希望对CoreCLR(用于.NET Core的框架的名称)做一些更改,以便简化移植工作。
我从MSDN发现了一个简短的比较
.NET Framework类库包含四个名为Timer的类,每个类提供不同的function:
System.Timers.Timer
,它触发一个事件,并定期在一个或多个事件接收器中执行代码。 该类旨在用作multithreading环境中的基于服务器或服务组件; 它没有用户界面,并且在运行时不可见。
System.Threading.Timer
,它定期在线程池线程上执行一个单一的callback方法。 当定时器被实例化时,callback方法被定义并且不能被改变。 像System.Timers.Timer类一样,这个类可以用作multithreading环境中基于服务器或服务的组件; 它没有用户界面,并且在运行时不可见。
System.Windows.Forms.Timer
,一个Windows窗体组件,它触发一个事件并定期在一个或多个事件接收器中执行代码。 该组件没有用户界面,devise用于单线程环境。
System.Web.UI.Timer
,一个定期执行asynchronous或同步网页回发的ASP.NET组件。
上面没有提到的一个重要的区别可能会引起你的注意,那就是System.Timers.Timer
默默吞下exception,而System.Threading.Timer
则不会。
例如:
var timer = new System.Timers.Timer { AutoReset = false }; timer.Elapsed += (sender, args) => { var z = 0; var i = 1 / z; }; timer.Start();
VS
var timer = new System.Threading.Timer(x => { var z = 0; var i = 1 / z; }, null, 0, Timeout.Infinite);
这两个类在function上是等价的,不同之处在于System.Timers.Timer
通过设置SynchronizingObject来select通过ISynchronizeInvoke来调用所有定时器到期callback函数 。 否则,两个定时器都会调用线程池线程上的过期callback。
将System.Timers.Timer
拖到Windows窗体devise图面上时,Visual Studio会将SynchronizingObject设置为表单对象,这将导致在UI线程上调用所有到期callback。
从MSDN: System.Threading.Timer
是一个简单,轻量级的计时器,使用callback方法,并由线程池线程提供服务。 不build议用于Windows窗体,因为它的callback不会在用户界面线程上发生。 System.Windows.Forms.Timer
是使用Windows窗体的更好select。 对于基于服务器的定时器function,您可以考虑使用System.Timers.Timer
,这会引发事件并具有其他function。
资源