TThread 中的 Application.ProcessMessages?

问题描述

在线程(不是主线程)内调用 Application.Processmessages 是否“可以”,还是应该预料到麻烦?

解决方法

TApplication.ProcessMessages() 主要用于处理 VCL 消息。您不应在工作线程中接收任何 VCL 消息,除非您正在从工作线程创建和显示 TForm 窗口。您不应该这样做,因为 VCL 不是线程安全的,不应在主 UI 线程之外使用。

但是,话虽如此,如果在工作线程中没有收到 VCL 消息,在工作线程中调用 ProcessMessages() 本身并没有什么害处。它会将任何接收到的消息(VCL 或其他)发送到调用线程中的适当窗口过程。但是,如果您认为需要在工作线程中手动发送消息,那么您首先确实需要质疑为什么需要这样做。除非您在工作线程中使用 COM 单元线程对象,或者将自定义线程消息发布到工作线程,否则在工作线程中运行消息循环几乎没有用,即使那样 ProcessMessages() 也不是理想的目的。

,

从主线程以外的线程调用 Application.ProcessMessages 确实是个坏主意,因为它确实是针对 VCL 的,而 VCL 不是线程安全的。

话虽如此,我有很多线程都有一个 message loop 以便它处理协作多任务和线程间通信。

我总是通过调用 Windows API 来编写自己的消息循环:

while GetMessage(MsgRec,0) do begin
    TranslateMessage(MsgRec);
    DispatchMessage(MsgRec)
end;

当异步 TWSocket 必须在线程中运行时,我会在我的 ICS(Internet 组件套件)中大量使用它。上面的代码是 TicsWndControl 中 ICS 的一部分。 TWSocket 每个线程可以轻松处理数百个连接,但如果要处理数千个连接,则必须使用线程。

在工作线程或主线程和工作线程之间使用 Windows 消息通常是一种避免调用 TThread.Synchronize 的解决方案:当您从一个线程 PostMessage 时,发送线程继续运行,而接收线程(创建的线程) PostMessage 中传递的窗口句柄)将在他自己的上下文中优雅地处理消息。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...