首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TTimer实际上是如何在内部工作的?

TTimer实际上是如何在内部工作的?
EN

Stack Overflow用户
提问于 2018-09-26 11:28:58
回答 2查看 390关注 0票数 1

间隔设置为1秒的TTimer每1秒发送一条消息。此消息将在应用程序的消息循环中处理,这将导致触发OnTimer事件。

如果应用程序很忙,并且没有时间处理消息循环,则跳过OnTimer事件。

我知道TTimer在内部使用SetTimer

我的问题是:

  1. TTimer是否使用内部/单独的线程(通过SetTimer)?
  2. 如果模态OnTimer正在“阻塞”表单,为什么持有定时器的表单(甚至它的MessageDlg )仍然可以执行任务?(见下文代码)
  3. 文档显示,SetTimer需要Win2000最小值。TTimer是如何在Win98中实现的?
代码语言:javascript
运行
复制
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 Caption = i;
 i++;
 MessageDlg(stuff);      <----- we "block" application here but form's caption is still updated.
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-26 15:18:14

如果应用程序很忙,并且没有时间处理消息循环,则跳过OnTimer事件。

这实际上是正确的。MSDN上的博客文章给出了一些内部实现细节,特别是它们提到,过期的计时器会导致设置消息队列状态的QS_TIMER标志。没有更长的时间间隔会导致队列状态标志被设置得更多。当设置此标志且[Peek|Get]Message无法选择任何更高优先级的消息时,将生成一个定时器消息。

虽然定时器消息不会堆积在队列中,但在执行前一个事件处理程序时,可以再次触发timer。当处理程序中的代码执行时间超过计时器间隔,并且允许重入时,这是可能的。如果计时器处理程序导致应用程序处理排队的消息,则可能清除任何挂起的队列状态标志,并再次发布消息,这可能会导致定时器在处理程序完成执行之前触发。

TTimer是否使用内部/单独的线程(通过SetTimer)?

不是的。在主线程中创建一个实用程序窗口,它将接收计时器消息。收到定时器消息后,如果指定了一个事件处理程序,此窗口将调用事件处理程序。

如果模态OnTimer正在“阻塞”表单,为什么持有定时器的表单(甚至它的MessageDlg )仍然可以执行任务?

模态循环继续处理队列,它在调用ProcessMessage的循环中调用应用程序的ProcessMessage。因此,计时器消息仍然被处理。

这是上述重新进入的一个潜在原因。您可以使用标志或禁用/启用计时器来防止这种情况发生。或将处理程序中的任何消息处理完全排除在外。

文档显示,SetTimer需要Win2000最小值。TTimer是如何在Win98中实现的

一样的。文档不断变化,偶尔MSDN会从最低要求中删除不支持的OS版本--这是不一致的。我的XE2 API文档声明:

最低操作系统 Windows 95,WindowsNT3.1

对于WM_TIMER消息。

票数 7
EN

Stack Overflow用户

发布于 2018-09-26 11:53:38

WM_TIMER消息从未放置在消息队列中。当队列为空并设置了指示计时器过期的标志时,将生成它们。因此,队列中一次不可能有多个WM_TIMER消息,如果应用程序太忙,无法处理队列,则不会收到大量等待处理的WM_TIMER消息。

WM_PAINT消息的工作方式是相同的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52516692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档