我的 Delphi 应用程序中有一个线程,它有一个消息等待循环。每次收到消息时,它都会开始做一些工作。这是该线程的执行过程:
procedure TMyThread.Execute;
begin
while GetMessage(Msg, 0, 0, 0) and not Terminated do
begin
{thread message}
if Msg.hwnd = 0 then
begin
...
end
else
DispatchMessage(Msg);
end;
end;
使用我的应用程序进行一些测试时,我发现 GetMessage 函数依赖于主线程。我的意思是,当主线程正在做一些工作时,我线程中的 GetMessage 函数不会返回,即使一条消息正在等待它接收(消息是由另一个线程使用 PostThreadMessage 函数发送的: PostMessage( MyThreadId, WM_MyMessage, 0, 0))。
只有当主线程完成其工作或调用 Application.ProcessMessages 方法时,GetMessage 才会返回并且我的线程开始工作。实现这种线程间通信我确信我的线程会独立工作,而且我永远不会期望直接发送到线程的消息的接收将依赖于主线程。
在进行测试时,我在主线程中使用了 WaitForSingleObject 函数,等待事件几秒钟。这是当我注意到我的线程没有做任何工作时,即使消息是由另一个线程发送给它的。当 WaitForSingleObject 函数终于完成等待并且主线程变得空闲时,我线程中的 GetMessage 函数返回了。
有人可以解释一下为什么它会这样工作吗?有解决方法吗?我想让我的线程独立接收消息。我所有的线程都是由主线程创建的。这可能是原因吗?
提前感谢您的帮助。
马吕斯。
Mghie,你又完全正确(你最近帮我处理了消息传递的问题,你可能还记得)。正如您所建议的, GetMessage 立即返回,但实际上,线程在调用主窗口方法时挂起:
procedure TMyThread.Execute;
begin
while GetMessage(Msg, 0, 0, 0) and not Terminated do
begin
{thread message}
if Msg.hwnd = 0 then
begin
...
if Assigned(FOnCommEventMethod) then
FOnCommEventMethod(FCommEventsQueueItem);
...
end
else
DispatchMessage(Msg);
end;
end;
FOnCommEventMethod 是一个对象的方法,声明为'procedure (EventMask: Cardinal) of object;' (此线程处理串行端口事件)。在这种情况下,FOnCommEventMethod 被分配了一个属于主窗体类的过程。当我的线程调用该方法时,线程挂起等待主线程完成其工作。
怎么会?如您所见,我不使用 Synchronize() 方法来调用此过程。因此,我不希望我的线程与主线程同步。它是否隐含地发生?顺便说一句,我知道除主线程之外的任何其他线程都不应访问任何 GUI 组件,因此应使用 Synchronize 方法,但我现在只做一些快速测试。
回到 WaitForSingleObject 主题,我知道我不应该使用它,但这只是一个测试(巧合地)我注意到了这个问题。
谢谢你的帮助。如果您不帮助我,我可能会摆脱消息传递并改用事件,最后我会注意到这不是原因:-)。