我需要编写一个执行计时操作并定期引发滴答事件的库类。我需要这个库可以在 WinForms 和非 WinForms 应用程序中使用。
问题在于,不同类型的应用程序的线程模型有很大不同。 WinForms 应用程序甚至有自己的专用计时器,但我事先不知道什么类型的应用程序会调用我。
是否有一种既定的模式可以安全地引发计时器事件,而无需事先了解将使用它的应用程序类型(WinForms、WPF、Silverlight、ASP.NET 等)?
I need to write a library class that performs timing operations, and raises a tick event periodically. I need this library to be usable from both WinForms and non-WinForms applications.
The problem is that the threading model is quite different for different types of applications. WinForms apps even have their own dedicated timers, but I don;t know in advance what type of app will be calling me.
Is there an established pattern for safely raising a timer event without prior knowledge of the type of app (WinForms, WPF, Silverlight, ASP.NET, etc.) that will use it?
发布评论
评论(1)
框架中有一些与平台无关的计时器:System.Threading。计时器和System.Timers.Timer 。但是,这些都需要您将封送处理回同步上下文,因为它们在线程池线程上引发事件。
您可以以通用方式提供此封送处理 - 即:创建一个包装上述内容之一的“计时器”类,采用 SynchronizationContext 作为参数。当计时器的 Tick 事件发生时,您可以发布 将数据返回到上下文。实际上,这就是 Windows 窗体计时器的作用。
然后,您只需在 UI 线程中创建它并将
SynchronizationContext.Current
传递给“新计时器”类。这适用于 Windows 窗体、WCF、WPF、Silverlight 等 - 因为它们都在其“主”线程上设置了 SynchronizationContext。There are timers that are platform neutral in the framework: System.Threading.Timer and System.Timers.Timer. However, these will both require you to handle the marshaling back to your synchronization context, as they raise their events on a threadpool thread.
You could provide this marshaling in a generic way - ie: make a "timer" class that wraps one of the above, taking a SynchronizationContext as an argument. When the timer's Tick event occurs, you could Post the data back to the context. This is, effectively, what the Windows Forms timer does.
You'd then just create it in your UI thread and pass
SynchronizationContext.Current
to the "new timer" class. This would work for Windows Forms, WCF, WPF, Silverlight, etc - as they all setup a SynchronizationContext on their "main" thread.