为什么要使用Windows.Forms.Timer?

6
我阅读了这篇优秀的文章《比较.NET Framework类库中的定时器类》,得出结论:任何我可以使用Windows.Forms.Timer做的事情,我都可以用Timers.Timer更好地完成 - 然后还有一些

那么显而易见的问题是:为什么还要提供Windows.Forms定时器?

遗留(向后兼容)支持?

其他原因?


文章链接已失效。 - tjmoore
6个回答

10
< p > Windows.Forms.Timer 的主要优点是其事件在 UI (Winforms) 线程上触发。如果您的计时器事件执行UI操作,这可能是最简单的替代方法(而不是在所有事件中调用< code > Control.Invoke/BeginInvoke 或 SynchronizationContext.Post/Send)。< /p>

你说得没错,使用'SynchronizingObject'来实现相同的功能确实更简单,但它使用起来有多困难呢?尤其是与更简单的定时器本身固有的"地雷"相比较。 - ih8ie8
2
阅读所有答案后,我倾向于认同您的答案:对于简单情况,编码的简洁性最为重要。但是,如果我将来想要在事件处理程序中添加一些耗时的非GUI处理...我就会遇到一个“定时炸弹”(双关语 :))。 - ih8ie8
@ih8ie8 - 使用SynchronizationContext非常容易:例如,您可以在窗体的构造函数中缓存它,类似于 _context = SynchronizationContext.Current,然后在事件处理程序中调用 _contex.Post/Send(...)。话虽如此,不必这样做甚至更简单 :) 当然,您关于长时间的非GUI工作的评论是正确的。 - Ohad Schneider

6

Windows.Forms.Timer提供了设计器支持。因此,它的行为就像任何其他Winforms组件(即可以将其拖动到窗体上,它是Controls集合的一部分等)。

System.Windows.Forms.Timer类引发的计时器事件与您的Windows Forms应用程序中的其余代码同步。这意味着正在执行的应用程序代码永远不会被此计时器类的实例抢占(假设您不调用Application.DoEvents)。由Windows.Forms.Timer类触发的事件与您的Winform控件兼容;您可以安全地与它们交互,而无需调用Invoke()

System.Timers.Timer类是一种基于服务器的计时器,专为多线程环境设计和优化。可以从多个线程安全地访问此计时器类的实例。虽然在技术上需要使用Invoke()与Winforms进行交互,但Timer类提供了一个SynchronizingObject属性,您可以将其中一个Windows窗体附加到该属性,以便安全地与其交互。

更多信息请参见: http://msdn.microsoft.com/en-us/magazine/cc164015.aspx


但是 Timers.Timer 也可以以同样的方式拖放,甚至为您处理 SynchronizingObject 属性...那么为什么要使用 Windows.Forms.Timer,当框架提供了一个更优秀的呢?也许是 CPU 效率? - ih8ie8
1
在所有的差异中,我认为最重要的是 Systems.Windows.Forms.Timer 在与 Winform 相同的线程上调用。它对于一些有用的事情非常方便,比如定期更新表单上的控件。如果你只需要一辆皮卡车,那么你不会开着轿车去上班。 - Robert Harvey

6
Windows.Forms.Timer 事件会在UI线程上调用,因此您可以直接从事件处理程序更新UI,而这通常不适用于Timers.Timer(因为您会遇到跨线程访问冲突异常)。 此外,正如@Robert Harvey 所回答的,它还具有设计器支持。

2
结论是:如果您需要操作GUI,则最好使用这个,它要简单得多,而且无需使用invoke。 - Alvin Wong
1
@AlvinWong - 我认为对于简单的场景来说使用它是更加容易的。 - Oded
@AlvinWong 当然你可以不用它,使用另一个计时器,但这只是更简单、更容易,并且需要更少的样板代码。按照同样的逻辑,如果你不想在UI线程中运行,你总是可以在表单计时器中启动一个后台线程,但这只是浪费资源。 - Servy
@Oded 如果我需要使用从访问缓慢的网页不断轮询的数据来操作GUI,该怎么办? - ih8ie8
@AlvinWong,就像其他两位所说的一样,我们不应该总是把一个用在另外一个的情况上,因为它们实际上有着完全不同的作用。 - Mike Perrenoud
显示剩余3条评论

6

Windows.Forms 的一个优点是它在 GUI 的同一线程中运行,因此在访问表单控件时不会出现跨线程异常。


3
我认为答案是,它们是两种完全不同类型的计时器。 Windows.Forms.Timer 是一个适用于运行在客户端应用程序上的单线程应用程序计时器。

计时器用于在用户定义的时间间隔内触发事件。这个Windows计时器专为单线程环境设计,其中UI线程用于执行处理。它要求用户代码有一个UI消息泵可用,并始终从同一线程操作,或将调用转移到另一个线程。

相比之下,Timers.Timer 是一种基于服务器的计时器,更适合于 Windows 服务。

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

您可以在 Microsoft 找到它们的文档并阅读摘录和更多内容。
并非永远不应该使用一个或总是使用另一个,他们服务于两个不同的目的。

0

我的信念是它是为了winform设计师集成而存在的,你可以将其拖放到表单上,单击它并在属性窗格中设置其属性。


但是 Timers.Timer 也可以以同样的方式拖放,甚至为您处理 SynchronizingObject 属性... - ih8ie8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接