delphi - Application.ProcessMessages 挂起?

标签 delphi delphi-2009 vcl

我的单线程delphi 2009应用程序(尚未完成)已经开始出现Application.ProcessMessages挂起的问题。我的应用程序有一个 TTimer 对象,每 100 毫秒触发一次以轮询外部设备。我使用 Application.ProcessMessages 在发生变化时更新屏幕,以便应用程序仍然具有响应能力。

其中一个是在网格 OnMouseDown 事件中。在那里,它有一个本质上挂起的 Application.ProcessMessages 。删除它没有问题,只是我很快发现另一个同样阻塞的 Application.ProcessMessages。

我认为我身上可能发生的情况是,TTimer(在我当前正在调试的应用程序模式下)可能需要很长时间才能完成。我已阻止 TTimer.OnTimer 事件处理程序重新输入相同的代码(见下文):

procedure TfrmMeas.tmrCheckTimer(Sender: TObject);
begin
  if m_CheckTimerBusy then
    exit;

  m_CheckTimerBusy:=true;
  try
    PollForAndShowMeasurements;
  finally
    m_CheckTimerBusy:=false;
  end;
end;

哪些地方调用 Application.ProcessMessages 是不好的做法? OnPaint 例程在我的脑海中浮现出一些毫无意义的东西。

有什么一般性建议吗?

我很惊讶地发现在开发的这个阶段出现了这种问题!

最佳答案

我对 TApplication.ProcessMessages 的建议是永远不要使用它 - 根本没有放置它的好点。

想象一下调用它会做什么:您的应用程序运行一个消息循环 - 其中 Windows 消息(由操作系统、其他应用程序、您的应用程序等生成)被顺序处理 - 并且在其中一个消息处理的中间,您只需再次重新运行整个消息循环,而无需控制将处理哪些消息、将有多少消息、是否有任何消息将进入其自己的消息循环......以及它们是否有任何可重入性问题与否。这就是我所说的自招麻烦

有时有很好的理由来处理一些窗口消息(特别是不挂起其他线程),或者处理定向到特定窗口的所有消息,但这可以通过更微妙的方式来完成,具有更多控制能力。

如果您必须在主GUI线程中进行任何处理,并且您只想更新界面,则可以使用TWinControl.Repaint方法来重绘GUI 元素。
如果您想让应用程序响应用户输入,您基本上必须使用后台/工作线程。

注意:在Delphi中,当在主线程中进行任何长时间的处理时,特别是如果涉及等待,您应该定期调用CheckSynchronize,以允许任何其他线程与主线程同步- 否则它们可能(并且可能会)挂起。
仅当应用程序空闲且处理 WM_NULL 消息时,VCL 才会调用此函数(假设不​​执行任何操作,这也可能会导致一些有趣的副作用)。

关于delphi - Application.ProcessMessages 挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3026882/

相关文章:

c# - VirtualProtect-AV : Attempted to read or write protected memory

delphi - 可以使用 IndexOf 在 Delphi 中的 TStringList 中搜索两个或多个替代字符串吗?

delphi - 为什么我的表单的 OnKeyDown 事件处理程序没有触发?

delphi - 当使用 --no-config 参数调用时,dcc32.exe 编译器会使用项目构建配置文件吗?

delphi - wsMaximized 表单不会出现最大化

.net - Delphi vcl.net应用及反编译

multithreading - Delphi (Indy) 线程安全类

delphi - 如何获取通用 TList<Integer> 中的最大值?

delphi - 将指针作为参数传递给构造函数时出现问题

c++ - 如何在 THeaderSection 中嵌入 VCL TEdit 控件?