gpt4 book ai didi

delphi - TTimer.OnTimer 事件处理程序是可重入的吗?

转载 作者:行者123 更新时间:2023-12-03 14:35:07 26 4
gpt4 key购买 nike

我的应用程序中有一个 TTimer,每 2 秒触发一次并调用我的事件处理程序 HandleTimerEvent()。 HandleTimerEvent() 函数会修改共享资源,并且在返回之前可能需要 10 秒的时间来执行。此外,我有时会在事件处理程序中调用 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 也一样)

是的,即使先前的事件处理程序仍在执行,TTimer.OnTimer 事件也可能被触发。如果您在事件处理程序中执行任何允许应用程序处理消息的操作,则可以重新输入计时器事件。显而易见的是,如果您的事件处理程序调用 Application.ProcessMessages,但它可能比这更微妙 - 如果您在事件处理程序中调用的任何内容在内部调用 Application.ProcessMessages,或调用 PeekMessage/GetMessage + DispatchMessage,或打开模式对话框,或调用绑定(bind)到进程外 COM 对象的 COM 接口(interface),然后应用程序消息队列中的消息将被处理,并且可能包括您的下一条 WM_Timer 消息。

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

关于delphi - TTimer.OnTimer 事件处理程序是可重入的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3311246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com