我正在尝试使用 Windows 计时器队列在 Windows GDI 上实现高每秒帧数。相关API为CreateTimerQueue, DeleteTimerQueueEx, CreateTimerQueueTimer,
和DeleteTimerQueueTimer
.
计时器是使用 CreateTimerQueueTimer(&m_timer, m_timer_queue, TimerCallback, this, 0, 20, WT_EXECUTEINTIMERTHREAD);
创建的达到大约 50fps 的速度。 GDI 操作(后台存储中的一些绘制,加上 InvalidateRect)不能异步,因此我不能选择除 WT_EXECUTEINTIMERTHREAD 之外的其他标志,以便绘制代码不需要额外的同步操作。我们的想法是在可能的情况下达到 50fps,如果不能,则以最大可能的速度显示每一帧。
动画结束时(达到总帧数),DeleteTimerQueueTimer
被调用来销毁计时器。
问题是 DeleteTimerQueueTimer
不会立即关闭回调函数的调用。当无法达到 50fps 要求时,计时器会将调用放入队列中。调用DeleteTimerQueueTimer
回调函数内部不会破坏队列。因此,即使决定关闭计时器,回调仍然被调用。
我该如何处理这个问题?
-
另一方面,旧的 timeSetEvent / timeKillEvent
多媒体API似乎没有这个问题。没有队列,当我调用 timeKillEvent 时,回调函数的调用立即停止。是否可以使用计时器队列实现相同的行为?
最佳答案
您可以将 WT_EXECUTEONLYONCE 标志传递给 CreateTimerQueueTimer 函数。这将导致计时器仅触发一次,而不是定期触发。
然后您可以使用 ChangeTimerQueueTimer 方法重新安排计时器。
为了覆盖帧中绘制时间过长而完成的情况,您可以将 CriticalSection 添加到 TimerHandler 方法的开头,这将导致第二个计时器等待第一个计时器完成。
关于windows - 定时器队列,立即终止定时器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1680162/