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的线程安全性 ,也许每个人都意味着:

  1. 当你使用定时器时很容易写出竞争条件。 例如看到这个问题: Timer(System.Threading)线程安全

  2. 定时器通知的重新进入,在定时器事件可以触发的地方,并在完成处理第一个事件之前再次打电话给您。 例如看到这个问题: 使用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。

资源