System.Timers.Timer与System.Threading.Timer

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

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

哪个最好?


#1楼

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

比较.NET Framework类库中的Timer类 ” - 也可用作.chm文件

具体的区别似乎是System.Timers.Timer适用于多线程应用程序,因此通过其SynchronizationObject属性是线程安全的,而System.Threading.Timer具有讽刺意味的是,它不是开箱即用的线程安全的。

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


#2楼

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

System.Timers.Timer是一个System.ComponentModel.Component ,它包装System.Threading.Timer ,并提供一些用于在特定线程上调度的附加功能。

System.Windows.Forms.Timer改为包装本机仅消息HWND,并使用Window Timers在该HWND消息循环中引发事件。

如果您的应用程序没有UI,并且您想要最轻量级和通用的.Net计时器,(因为您很高兴找到自己的线程/调度),那么System.Threading.Timer就像它获得的一样好框架。

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

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

  2. 计时器通知的重新进入,您的计时器事件可以触发,并在您完成第一个事件的处理之前第二次回拨您。 例如,请参阅此问题: 使用System.Threading.Timer和Monitor进行线程安全执行


#3楼

我在MSDN上找到了一个简短的比较

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

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

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

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

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


#4楼

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

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


#5楼

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

资源


#6楼

上面没有提到的一个可能会让你感到System.Timers.Timer重要区别是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);

#7楼

Microsoft提供的有关此信息(请参阅MSDN上的备注 ):

  • System.Timers.Timer ,它会定期触发事件并在一个或多个事件接收器中执行代码。 该类旨在用作多线程环境中的基于服务器或服务组件; 它没有用户界面,在运行时不可见。
  • System.Threading.Timer ,它定期在线程池线程上执行单个回调方法。 回调方法是在实例化定时器时定义的,无法更改。 与System.Timers.Timer类一样,此类旨在用作多线程环境中的基于服务器或服务组件; 它没有用户界面,在运行时不可见。
  • 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加载项建议使用System.Threading.Timer

看起来Microsoft在System.Threading.Timer之前支持System.Timers.Timer

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


#8楼

在他的书“ CLR Via C# ”中, Jeff Ritcher不鼓励使用System.Timers.Timer ,这个计时器派生自System.ComponentModel.Component ,允许它在Visual Studio的设计界面中使用。 因此,只有在设计图面上需要计时器时它才有用。

他更喜欢使用System.Threading.Timer来处理线程池线程上的后台任务。

发布了0 篇原创文章 · 获赞 1 · 访问量 3222

猜你喜欢

转载自blog.csdn.net/asdfgh0077/article/details/103946769
今日推荐