System.Timers.Timer与System.Threading.Timer

时间:2009-09-13 03:56:10

标签: .net timer

我最近一直在检查一些可能的计时器,而Threading.TimerTimers.Timer是那些看起来需要我的人(因为它们支持线程池)。

我正在制作游戏,我计划使用不同类型的活动,间隔不同等。

哪个最好?

9 个答案:

答案 0 :(得分:346)

本文提供了相当全面的解释:

Comparing the Timer Classes in the .NET Framework Class Library” - 也可用as a .chm file

具体差异似乎是System.Timers.Timer面向多线程应用程序,因此通过其SynchronizationObject属性是线程安全的,而System.Threading.Timer具有讽刺意味的是不是线程安全的。 -the-框。

我不认为两者之间存在差异,因为它与你的间隔有多小有关。

答案 1 :(得分:153)

System.Threading.Timer是一个简单的计时器。它会回调一个线程池线程(来自工作池)。

System.Timers.Timer是一个包含System.ComponentModel.Component的{​​{1}},并提供了一些用于在特定线程上进行调度的附加功能。

System.Threading.Timer改为包装原生message-only-HWND并使用Window Timers在该HWND消息循环中引发事件。

如果您的应用没有用户界面,并且您想要最轻量级和通用的.Net计时器,(因为您很高兴找到自己的线程/调度),那么System.Windows.Forms.Timer就像它进入了框架。

我还不完全清楚System.Threading.Timer所谓的'不线程安全'问题是什么。也许它与这个问题中的问题相同:Thread-safety of System.Timers.Timer vs System.Threading.Timer,或者也许每个人只是意味着:

  1. 当您使用计时器时,很容易写出竞争条件。例如。看到这个问题: Timer (System.Threading) thread safety

  2. 计时器通知的重新发生,您可以触发计时器事件,并在完成处理第一个事件之前回拨第二时间。例如。看到这个问题:Thread-safe execution using System.Threading.Timer and Monitor

答案 2 :(得分:117)

在他的书“ CLR通过C#”中, Jeff Ritcher 不鼓励使用System.Timers.Timer,此计时器来自System.ComponentModel.Component,允许它用于Visual Studio的设计表面。因此,只有在设计图面上需要计时器时才会有用。

他更喜欢在线程池线程上使用System.Threading.Timer作为后台任务。

答案 3 :(得分:32)

Microsoft提供的有关此信息(请参阅Remarks on MSDN):

  
      
  • System.Timers.Timer,   它会触发事件并在一个或多个事件接收器中执行代码   定期。该类旨在用作基于服务器的   或多线程环境中的服务组件;它没有用户   界面,在运行时不可见。
  •   
  • System.Threading.Timer,   它在线程池线程上执行单个回调方法   定期。定时器时定义了回调方法   实例化,无法更改。像System.Timers.Timer一样   class,此类旨在用作基于服务器或服务   多线程环境中的组件;它没有用户界面和   在运行时不可见。
  •   
  • System.Windows.Forms.Timer   (仅限.NET Framework),用于触发事件的Windows窗体组件   并定期在一个或多个事件接收器中执行代码。   该组件没有用户界面,设计用于   单线程环境;它在UI线程上执行。
  •   
  • System.Web.UI.Timer   (仅限.NET Framework),一个执行异步的ASP.NET组件   或定期间隔的同步网页回发。
  •   

有趣的是,System.Timers.Timer已被.NET Core 1.0弃用,但在.NET Core 2.0(/ .NET Standard 2.0)中再次实现。 .NET Standard 2.0的目标是尽可能简单地从.NET Framework切换,这可能就是它回归的原因。

不推荐使用时,.NET Portability Analyzer Visual Studio Add-In建议改为使用System.Threading.Timer

看起来Microsoft在System.Threading.Timer之前赞成System.Timers.Timer

编辑说明2018-11-15: 由于有关.NET Core 1.0的旧信息不再有效,我提交了更改我的答案。

答案 4 :(得分:30)

上面没有提到的一个可能会让你感到震惊的重要区别是System.Timers.Timer默默地吞下异常,而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);

答案 5 :(得分:24)

我找到了MSDN

的简短比较
  

.NET Framework类库包含四个名为Timer的类,   每个都提供不同的功能:

     

System.Timers.Timer,它会触发事件并定期在一个或多个事件接收器中执行代码。这个课程是有意的   用作多线程中的基于服务器或服务组件   环境;它没有用户界面,在运行时不可见。

     

System.Threading.Timer,它定期在线程池线程上执行单个回调方法。回调方法是   定时器实例化时定义且无法更改。像   System.Timers.Timer类,此类旨在用作   多线程环境中基于服务器或服务组件;它   没有用户界面,在运行时不可见。

     

System.Windows.Forms.Timer,一个Windows窗体组件,用于触发事件并在常规的一个或多个事件接收器中执行代码   间隔。该组件没有用户界面,专为使用而设计   在单线程环境中。

     

System.Web.UI.Timer,一个ASP.NET组件,定期执行异步或同步网页回发。

答案 6 :(得分:1)

这两个类在功能上是等效的,除了System.Timers.Timer有一个选项可以通过ISynchronizeInvoke通过SynchronizingObject调用所有定时器到期回调。否则,两个计时器都会在线程池线程上调用过期回调。

System.Timers.Timer拖到Windows窗体设计图面上时,Visual Studio会将SynchronizingObject设置为窗体对象,这会导致在UI线程上调用所有过期回调。

答案 7 :(得分:1)

来自MSDN:System.Threading.Timer是一个简单,轻量级的计时器,它使用回调方法并由线程池线程提供服务。不建议将其与Windows窗体一起使用,因为它的回调不会发生在用户界面线程上。 System.Windows.Forms.Timer是与Windows窗体一起使用的更好选择。对于基于服务器的计时器功能,您可以考虑使用System.Timers.Timer,它会引发事件并具有其他功能。

Source

答案 8 :(得分:0)

正如其他人提到的指向 MS Docs 的链接,System.Timers.TimerSystem.Threading.Timer 之间的一个主要区别是 System.Threading.Timer 执行一个单个回调方法<强>定义一次,而 System.Timers.Timer 对事件作出反应,因此支持多个订阅者,这些订阅者也可以删除。

如上所述,System.Timers.Timer 在内部使用 System.Threading.Timer,例如Enable=false 处理内部计时器,并在 Enable=true / Start() 上重新创建它: https://source.dot.net/#System.ComponentModel.TypeConverter/System/Timers/Timer.cs