将 SetTimer() 和 KillTimer() 移植到 C#?

Posted

技术标签:

【中文标题】将 SetTimer() 和 KillTimer() 移植到 C#?【英文标题】:Porting SetTimer() and KillTimer() to C#? 【发布时间】:2011-04-21 21:22:26 【问题描述】:

我正在尝试将一些代码从 C++ 移植到 C#。

我在 C++ 代码中遇到了这个:

watchdogTimer = SetTimer(1,1000,NULL);
...
KillTimer(watchdogTimer);

这段代码在做什么,如何移植到 C#?

谢谢。

【问题讨论】:

【参考方案1】:

您正在查看的CWnd::SetTimer 函数创建了一个将WM_TIMER 事件发送到窗口的计时器。这类似于 .NET 中的 System.Windows.Forms.Timer 组件。它的行为与System.Timers.Timer 略有不同。有两个特别相关的区别:

Windows.Forms.Timer 调用 UI 线程上的事件处理程序。默认情况下,System.Timers.Timer 调用线程池线程上的事件处理程序。您可以使用 SynchronizingObject 属性在 UI 线程上调用 System.Timers.Timer

另一个区别是,Windows 窗体计时器不可能遇到重入问题,因为 Windows 不允许队列中来自同一计时器的多个 WM_TIMER 消息,也不会在队列中放置 WM_TIMER 消息如果一个已经在处理中。这通常是一件好事。

另一方面,System.Timers.Timer 将允许重入。因此,如果您的计时器事件处理程序花费的时间比计时器周期长,您可以同时为同一个计时器处理多个事件。如果您的计时器周期为 100 毫秒并且处理需要 150 毫秒,那么您将在处理第一个通知时收到另一个通知。如果您使用SynchronizingObject 强制在 UI 线程上进行回调,这可能会导致一大堆待处理的回调排队。

这两个定时器的实现是完全不同的。 Windows 窗体计时器使用已有 20 年历史的旧样式 Windows timers。这种类型的定时器需要一个窗口句柄和一个消息循环,因此只在 GUI 程序中使用。 System.Timers.TimerSystem.Threading.Timer 的一个薄包装,它使用 Windows Thread Pool Timers。

【讨论】:

感谢吉姆更深入的回答。【参考方案2】:

假设你的应用程序是在 MFC 下编写的,SetTimer() 方法属于 CWnd 类,负责设置一个 windows 计时器。这方面的文档可以在http://msdn.microsoft.com/en-us/library/49313fdf(v=vs.80).aspx 找到。我对 .NET 知之甚少,但通过 google 快速搜索发现以下内容:http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx。

【讨论】:

谢谢乔恩。在查看了这些页面后,我认为 System.Timers.Timer 可以解决问题。如果我错了,请纠正我。 @Ryan,只需使用System.Timers.Timer 就足够了。这将是一个非常不寻常的情况,您需要自己实际设置一个窗口计时器。

以上是关于将 SetTimer() 和 KillTimer() 移植到 C#?的主要内容,如果未能解决你的问题,请参考以下文章

问下关于MFC中 SetTimer() 和 KillTimer() 的使用

settimer函数的使用例子

SetTimer IDEvent 返回值问题

delphi中setTimer函数的用法

SetTimer API函数

VC中使用 setTimer 定时器时,可否当出现结果错误时跳出本次定时器触发的运行程序,执行下一次的定时触发?