我有一个使用CreateTimerQueueTimer和DeleteTimerQueueTimer的计时器类。我按预期收到类对象的回调。当应用程序忙于绘制UI或进行密集渲染等时,如何确保计时器不会触发?我不关心高分辨率,只是当应用程序空闲时它必须触发。
我正在使用以下内容来创建计时器。
BOOL timerCreated = ::CreateTimerQueueTimer(&mTimerRef,
NULL,
TimerCallback,
(PVOID)(this),
inFireDelay * 1000,
inInterval * 1000,
WT_EXECUTEINUITHREAD);
// using timer queues because i dont have access to a hWnd in this class.
抱歉,我不能仅使用MFC / .NET,只能使用win32。
谢谢, 阿希奈。
答案 0 :(得分:3)
这通常是不可能的。回调是在线程池线程上进行的,你不能挥动魔术旗并问“请不要开火”。即使有可能,这是一个不可避免的竞争条件,该线程可能已经启动但尚未有机会执行。
您所能做的就是阻止线程,在回调中使用关键部分或互斥锁。当你的UI线程“不空闲”时获取互斥锁是非常不切实际的,你必须在你的消息循环中这样做。通常,您只想保护在UI线程和回调中都可以访问的共享状态变量。
如果您正在考虑这个问题,因为您不希望回调在您的UI线程繁忙时消耗CPU周期,请记住,现在几乎所有计算机都至少有两个CPU核心。这个问题不需要修复。
答案 1 :(得分:0)
WRT:// using timer queues because i dont have access to a hWnd in this class.
您不需要将hWnd传递给SetTimer - 您只需注册一个被回调的定时器proc。 WM_TIMER消息是低优先级的,只有当没有其他消息未决时才由消息队列生成,因此您可以自动获得所需的行为。
如果定时器消息正在进行绘制,那么无论如何都会有很多争用设备驱动程序来串行化线程池的可能性,但是多核CPU是常态,在工作线程中进行定时器处理不必干扰完全使用UI线程。