3个Timer的区别(System.Threading.Timer,System.Windows.Forms.Timer,System.Timers.Timer)

时间:2022-03-05 20:34:09
最近要做一计费系统,将会开多个线程并启动多个Timer进行并发计费。
所以想搞清楚一下三个Timer的区别,选一个耗资源比较少又较精确的Timer.[考虑的峰值为1000个Timer]
大家可以一起学习一下。

我所了解的(不对的地方麻烦指出来):
Windows.Forms.Timer是通过windows的消息机制发送Timer事件。它仅可在能处理windows消息循环的线程使用。
Threading.Timer是最轻量级的,它将在系统线程池分配的线程中定时运行,所以每次运行的线程不一定相同。
Timers.Timer在MSDN上说是为服务器设计的,但没明白它的优势是什么,是否是最精确的?耗资源呢?

22 个解决方案

#1


System.Timers.Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发 Elapsed 事件的周期性间隔。然后可以操控此事件以提供定期处理。例如,假设您有一台关键性服务器,必须每周 7 天、每天 24 小时都保持运行。可以创建一个使用 Timer 的服务,以定期检查服务器并确保系统开启并在运行。如果系统不响应,则该服务可以尝试重新启动服务器或通知管理员。

#2


基于服务器的计时器允许指定在应用程序中引发事件的重复时间间隔。然后可通过处理这个事件来提供常规处理。例如,假设您有一台关键的服务器,必须保持一周 7 天、一天 24 小时连续运行。您可以创建一个服务,通过使用计时器来定期检查关键的服务器,确保系统启动并运行。如果该系统没有响应,此服务可以尝试重新启动服务器或通知系统管理员。

注意   以毫秒为单位指定服务器计时器的时间间隔。
服务器计时器、Windows 计时器和线程计时器
在 Visual Studio .NET 和 .NET Framework 中有三种计时器控件:基于服务器的计时器,位于“工具箱”的“组件”选项卡上;基于 Windows 的标准计时器,位于“工具箱”的“Windows 窗体”选项卡上,以及仅可在编程时使用的线程计时器。基于 Windows 的计时器从 Visual Basic 的 1.0 版起就存在于该产品中并且基本上保持不变。该计时器已经为在 Windows 窗体应用程序中使用而进行了优化。基于服务器的计时器是传统的计时器为了在服务器环境上运行而优化后的更新版本。线程计时器是一种简单的、轻量级计时器,使用回调方法而不是事件,并由线程池线程提供。

在 Win32 体系结构中有两种类型的线程:UI 线程和辅助线程。UI 线程绝大多数时间处于空闲状态,等待消息循环中的消息到来。一旦接收到消息,它们就进行处理并等待下一个消息到来。另外,辅助线程用来执行后台处理而且不使用消息循环。Windows 计时器和基于服务器的计时器在运行时都使用 Interval 属性。线程计时器的时间间隔在 Timer 构造函数中设置。计时器的设计目的各不相同,它们的线程处理明确地指出了这一点: 

Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。Windows 计时器的精度限定为 55 毫秒。这些传统计时器要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。对于 COM 组件来说,这样会降低性能。 
基于服务器的计时器是为在多线程环境下与辅助线程一起使用而设计的。由于它们使用不同的体系结构,因此基于服务器的计时器可能比 Windows 计时器精确得多。服务器计时器可以在线程之间移动来处理引发的事件。 
对消息不在线程上发送的方案中,线程计时器是非常有用的。例如,基于 Windows 的计时器依赖于操作系统计时器的支持,如果不在线程上发送消息,与计时器相关的事件将不会发生。在这种情况下,线程计时器就非常有用。 
Windows 计时器位于 System.Windows.Forms 命名空间中,服务器计时器位于 System.Timers 命名空间中,而线程计时器位于 System.Threading 命名空间中。

#3


xuexi

#4


那么:
System.Timers.Timer会依赖于服务器?(windows server2000和windows server2003才可以?)
如果依赖服务器,那么是否可以减轻当前进程的负担?
是不是说System.Timers.Timer就是最耗资源的呢?
如果我要创建的计时器可能达1000个,是否应该使用System.Threading.Timer而不应该使用System.Timers.Timer呢?

我希望精确,但不能让系统崩溃,呵呵。谢谢大侠!
                                          ----楼主

#5


关注

#6


关注

#7


很佩服楼主精益求精的精神,我以前也没区分过,因为没有这种需求.

我的理解是如果达到1000个以上的话,就应该使用占用资源较少的线程计时器

#8


呵呵,谢谢立冬夸奖:)

我也是认为应该用线程计时器,我有点担心在线程很多的时候计时器会不会变得很不精确。当然,测一下就知道了,有空了我去测一下。

#9


System.Windows.Forms.Timer是单线程的。。。通俗的说使用这个计时器执行方法的时候画面会卡住

而另2个你不需要,为了执行效率,为其执行的方法开线程。

#10


GZ

#11


干吗要这么多计时器

#12


to hatita(悠远的风景):
这些Timer的分配本身都是不在一个线程中的,但其实这不重要,因为System.Threading.Timer本身就是在系统线程池中分配的线程执行的。System.Timers.Timer应该也是。

to zhy0101(香蕉):
要进行实时计费,只有开一个Timer每分钟检查一次。还有个方法是不停的遍历链表(计费信息放在链表中),我担心不停的遍历会对系统开销太大,对Socket连接产生影响。如果隔一段时间遍历一次又达不到实时效果。

谢谢大家。望大侠继续赐教。目前我是使用的System.Threading.Timer,感觉不是很精确。
                                                  ----楼主

#13


不会吧!过年了都没人帮忙呀!

                                   ----楼主

#14


感觉上,Windows计时器就是命令Windows在多久之后为自己发一条消息,然后再被自己的消息循环捕获。
那么缺点是很显而易见的,就是如果消息队列中的消息太多,或者当前主线程被阻塞的时候,这条计时消息就可能在很晚的时候才被处理。

而服务器Timer很明显是另开一个线程计时,每一个Timer是一个独立的线程,独立的计时,所以精度非常高,并且Elapsed事件是在独立的线程上触发的。

#15


关注

#16


楼主很细心,没仔细想过这么多,帮顶一下

#17


首先谢谢Ivony() 的关注,不过,你说的我都知道,我是想弄清楚Threading.Timer和Times.Timer的区别。
                                    ----楼主

#18


System.Threading.Timer与System.Timers.Timer的区别 

http://blog.joycode.com/gangp/archive/2004/07/18/27745.aspx

#19


Comparing the Timer Classes in the .NET Framework Class Library

http://msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET/

System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
Thread-safe Programming with Timers
Dealing with Timer Event Reentrance
Conclusion

#20


也就是说System.Threading.Timers不管new多少个,实际上都只会有一个线程是吗? 
Waitable Timer是什么实现我不懂,那么能不能直接的说一下,两个Timer的性能,精确度呢? 
我可能得用几百个Timer,是该用Threading.Timer还是Timers.Timer? 
                                    ----楼主

#21


关注!

#22


如果想要达到实时的效果,应该是用事件的机制,也就是说在进行和费用相关的操作的时候,应该触发进行如充值日志记录、帐户余额计算等事件,这样才能得到实时的计费信息。靠定时器来扫描肯定不是一个好的方案。定时器一般是用来做例如客户端里验证远程服务器是否可用这种类型的事情的。

#1


System.Timers.Timer 组件是基于服务器的计时器,它使您能够指定在应用程序中引发 Elapsed 事件的周期性间隔。然后可以操控此事件以提供定期处理。例如,假设您有一台关键性服务器,必须每周 7 天、每天 24 小时都保持运行。可以创建一个使用 Timer 的服务,以定期检查服务器并确保系统开启并在运行。如果系统不响应,则该服务可以尝试重新启动服务器或通知管理员。

#2


基于服务器的计时器允许指定在应用程序中引发事件的重复时间间隔。然后可通过处理这个事件来提供常规处理。例如,假设您有一台关键的服务器,必须保持一周 7 天、一天 24 小时连续运行。您可以创建一个服务,通过使用计时器来定期检查关键的服务器,确保系统启动并运行。如果该系统没有响应,此服务可以尝试重新启动服务器或通知系统管理员。

注意   以毫秒为单位指定服务器计时器的时间间隔。
服务器计时器、Windows 计时器和线程计时器
在 Visual Studio .NET 和 .NET Framework 中有三种计时器控件:基于服务器的计时器,位于“工具箱”的“组件”选项卡上;基于 Windows 的标准计时器,位于“工具箱”的“Windows 窗体”选项卡上,以及仅可在编程时使用的线程计时器。基于 Windows 的计时器从 Visual Basic 的 1.0 版起就存在于该产品中并且基本上保持不变。该计时器已经为在 Windows 窗体应用程序中使用而进行了优化。基于服务器的计时器是传统的计时器为了在服务器环境上运行而优化后的更新版本。线程计时器是一种简单的、轻量级计时器,使用回调方法而不是事件,并由线程池线程提供。

在 Win32 体系结构中有两种类型的线程:UI 线程和辅助线程。UI 线程绝大多数时间处于空闲状态,等待消息循环中的消息到来。一旦接收到消息,它们就进行处理并等待下一个消息到来。另外,辅助线程用来执行后台处理而且不使用消息循环。Windows 计时器和基于服务器的计时器在运行时都使用 Interval 属性。线程计时器的时间间隔在 Timer 构造函数中设置。计时器的设计目的各不相同,它们的线程处理明确地指出了这一点: 

Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理。Windows 计时器的精度限定为 55 毫秒。这些传统计时器要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用封送到另一个线程。对于 COM 组件来说,这样会降低性能。 
基于服务器的计时器是为在多线程环境下与辅助线程一起使用而设计的。由于它们使用不同的体系结构,因此基于服务器的计时器可能比 Windows 计时器精确得多。服务器计时器可以在线程之间移动来处理引发的事件。 
对消息不在线程上发送的方案中,线程计时器是非常有用的。例如,基于 Windows 的计时器依赖于操作系统计时器的支持,如果不在线程上发送消息,与计时器相关的事件将不会发生。在这种情况下,线程计时器就非常有用。 
Windows 计时器位于 System.Windows.Forms 命名空间中,服务器计时器位于 System.Timers 命名空间中,而线程计时器位于 System.Threading 命名空间中。

#3


xuexi

#4


那么:
System.Timers.Timer会依赖于服务器?(windows server2000和windows server2003才可以?)
如果依赖服务器,那么是否可以减轻当前进程的负担?
是不是说System.Timers.Timer就是最耗资源的呢?
如果我要创建的计时器可能达1000个,是否应该使用System.Threading.Timer而不应该使用System.Timers.Timer呢?

我希望精确,但不能让系统崩溃,呵呵。谢谢大侠!
                                          ----楼主

#5


关注

#6


关注

#7


很佩服楼主精益求精的精神,我以前也没区分过,因为没有这种需求.

我的理解是如果达到1000个以上的话,就应该使用占用资源较少的线程计时器

#8


呵呵,谢谢立冬夸奖:)

我也是认为应该用线程计时器,我有点担心在线程很多的时候计时器会不会变得很不精确。当然,测一下就知道了,有空了我去测一下。

#9


System.Windows.Forms.Timer是单线程的。。。通俗的说使用这个计时器执行方法的时候画面会卡住

而另2个你不需要,为了执行效率,为其执行的方法开线程。

#10


GZ

#11


干吗要这么多计时器

#12


to hatita(悠远的风景):
这些Timer的分配本身都是不在一个线程中的,但其实这不重要,因为System.Threading.Timer本身就是在系统线程池中分配的线程执行的。System.Timers.Timer应该也是。

to zhy0101(香蕉):
要进行实时计费,只有开一个Timer每分钟检查一次。还有个方法是不停的遍历链表(计费信息放在链表中),我担心不停的遍历会对系统开销太大,对Socket连接产生影响。如果隔一段时间遍历一次又达不到实时效果。

谢谢大家。望大侠继续赐教。目前我是使用的System.Threading.Timer,感觉不是很精确。
                                                  ----楼主

#13


不会吧!过年了都没人帮忙呀!

                                   ----楼主

#14


感觉上,Windows计时器就是命令Windows在多久之后为自己发一条消息,然后再被自己的消息循环捕获。
那么缺点是很显而易见的,就是如果消息队列中的消息太多,或者当前主线程被阻塞的时候,这条计时消息就可能在很晚的时候才被处理。

而服务器Timer很明显是另开一个线程计时,每一个Timer是一个独立的线程,独立的计时,所以精度非常高,并且Elapsed事件是在独立的线程上触发的。

#15


关注

#16


楼主很细心,没仔细想过这么多,帮顶一下

#17


首先谢谢Ivony() 的关注,不过,你说的我都知道,我是想弄清楚Threading.Timer和Times.Timer的区别。
                                    ----楼主

#18


System.Threading.Timer与System.Timers.Timer的区别 

http://blog.joycode.com/gangp/archive/2004/07/18/27745.aspx

#19


Comparing the Timer Classes in the .NET Framework Class Library

http://msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET/

System.Windows.Forms.Timer
System.Timers.Timer
System.Threading.Timer
Thread-safe Programming with Timers
Dealing with Timer Event Reentrance
Conclusion

#20


也就是说System.Threading.Timers不管new多少个,实际上都只会有一个线程是吗? 
Waitable Timer是什么实现我不懂,那么能不能直接的说一下,两个Timer的性能,精确度呢? 
我可能得用几百个Timer,是该用Threading.Timer还是Timers.Timer? 
                                    ----楼主

#21


关注!

#22


如果想要达到实时的效果,应该是用事件的机制,也就是说在进行和费用相关的操作的时候,应该触发进行如充值日志记录、帐户余额计算等事件,这样才能得到实时的计费信息。靠定时器来扫描肯定不是一个好的方案。定时器一般是用来做例如客户端里验证远程服务器是否可用这种类型的事情的。