TTimer.OnTimer事件处理程序是否可重入? [英] Is the TTimer.OnTimer event handler reentrant?

查看:228
本文介绍了TTimer.OnTimer事件处理程序是否可重入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序中有一个TTimer,每2秒触发一次,并调用我的事件处理程序HandleTimerEvent()。 HandleTimerEvent()函数修改共享资源,可以在返回前执行几秒钟。此外,我在事件处理程序中调用Sleep()可以放弃处理器。



我不知道C ++ Builder的TTimer对象在调用事件时如何工作所以我刚刚解释的情况让我有所思考,特别是HandleTimerEvent()是否在之前的调用返回之前被调用。



问题归结为几个



TTimer对象是否排队事件?



TTimer对象可以在之前调用我的事件处理程序先前的电话已经返回?

解决方案

此回复假设TTimer仍然实现为使用WM_Timer消息。如果实现已经改变(自2005年以来),请忽略。



不,TTimer对象不排队事件。它由Windows WM_Timer消息驱动,Windows不让WM_TIMER消息堆栈在消息队列中。如果下一个定时器间隔发生,Windows看到WM_Timer消息已经在应用程序的消息队列中,它不会向队列中添加另一个WM_Timer消息。 (与WM_Paint,btw相同)



是的,即使先前的事件处理程序仍在执行,TTimer.OnTimer事件也可能被触发。如果您在事件处理程序中执行允许应用程序处理消息的任何操作,则可以重新启动计时器事件。明显的一个是如果你的事件处理程序调用Application.ProcessMessages,但它可以比这更微妙 - 如果你在事件处理程序中调用的任何内部调用Application.ProcessMessages,或者调用PeekMessage / GetMessage + DispatchMessage,或打开一个模态对话框,或者调用绑定到进程外COM对象的COM接口,那么应用程序消息队列中的消息将被处理,并且可能包含下一个WM_Timer消息。



一个简单的解决方案是在您输入定时器事件处理程序时禁用定时器对象,并在退出定时器事件处理程序时重新启用它。这将阻止计时器消息在您的事件处理程序仍在工作时触发,无论代码的消息处理特性如何。


I have a TTimer in my application that fires every 2 seconds and calls my event handler, HandleTimerEvent(). The HandleTimerEvent() function modifies shared resources and can take 10's of seconds to execute before returning. Furthermore, I call Sleep() in the event handler to relinquish the processor at times.

I'm not sure how C++ builder's TTimer object works when it comes to calling events, so the scenario I just explained has got me thinking, particularly, whether HandleTimerEvent() gets called before a prior call has returned.

The question comes down to a couple of things.

Does the TTimer object queue the events?

Can the TTimer object call my event handler before a prior call has returned?

解决方案

This reply assumes that TTimer is still implemented to use WM_Timer messages. If the implementation has changed (since 2005), please disregard.

No, the TTimer object does not queue events. It is driven by the Windows WM_Timer message, and Windows does not let WM_TIMER messages stack up in the message queue. If the next timer interval occurs and Windows sees that a WM_Timer message is already in the app's message queue, it does not add another WM_Timer messsage to the queue. (Same for WM_Paint, btw)

Yes, it is possible for a TTimer.OnTimer event to be fired even while a prior event handler is still executing. If you do anything in your event handler that allows the app to process messages, then your timer event can be reentered. The obvious one is if your event handler calls Application.ProcessMessages, but it can be much more subtle than that - if anything you call in your event handler internally calls Application.ProcessMessages, or calls PeekMessage/GetMessage + DispatchMessage, or opens a modal dialog, or calls a COM interface that is bound to an out-of-process COM object, then messages in your app message queue will be processed and that could include your next WM_Timer message.

A simple solution is to disable the timer object when you enter your timer event handler, and reenable it when you exit your timer event handler. This will prevent timer messages from firing while your event handler is still working, regardless of the message handling characteristics of your code.

这篇关于TTimer.OnTimer事件处理程序是否可重入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆