【发布时间】:2015-02-27 18:37:55
【问题描述】:
我正在开发一个 Delphi XE4 服务应用程序。该服务为一些长时间运行的任务启动线程,线程通过 PostThreadMessage 调用返回状态。
ServiceExecute 主循环如下所示:
procedure TScanService.ServiceExecute(Sender: TService);
var
CurrentMessage: TMsg;
begin
LogServerEvent('ServiceExecute', 'Starting');
while not Terminated do
begin
if not PeekMessage(CurrentMessage, 0, WM_NULL, msgHigh, PM_NOREMOVE) then
begin
Sleep(1000);
Continue;
end;
GetMessage(CurrentMessage, 0, WM_NULL, msgHigh);
LogServerEvent('ServiceExecute', 'CurrentMessage.message', IntToStr(CurrentMessage.message));
LogServerEvent('ServiceExecute', 'CurrentMessage.wParam', IntToStr(CurrentMessage.wParam));
LogServerEvent('ServiceExecute', 'CurrentMessage.lParam', IntToStr(CurrentMessage.lParam));
在线程中,消息发送如下:
gThreadNumber: Integer;
LogThreadEvent('Execute', 'Found Notice, Thread number: ' + IntToStr(gThreadNumber));
PostThreadMessage(ParentThreadID, msgFound, gThreadNumber, 6);
消息到达正常,消息号正确(msgFound = WM_USER + 1);但是,我为 wParam、lParam 发送了 0、6,而我收到的是 4、0。我错过了什么?
注意:代码只运行了 2 个线程,其中一个是使用不同消息编号的计时器,并且在发生这种情况时不发送任何内容。
【问题讨论】:
-
奇怪的消息循环,你可以单独使用GetMessage来阻止,直到有消息发布。
-
我在您发布的代码中没有发现问题,这意味着问题可能不在您发布的代码中。你能把它缩减成一个小样本来演示我们可以实际编译和运行来重现它的问题吗?
-
你没有选择你的
HWND... RTL 使用WM_USER + x范围内的一些消息;没有更多代码很难说,但是您可能会收到杂散的消息。如果您将-1用于PeekMessage和GetMessage的HWND参数,您将限制只接收使用NULLHWND 发布的消息(否则您还会收到窗口消息)- 前者只会包含消息使用带有空句柄的PostMessage发送,使用PostThreadMessage发送的消息。 -
@J...:不错的收获。我错过了。我通常使用 PostThreadMessage 在线程和 GUI 之间进行通信,并在收到消息时始终检查
Msg.hwnd = 0;我没想过通过服务这样做。 -
CM_SERVICE_CONTROL_CODE 是 WM_USER + 1,wparam 为 4 是 SERVICE_CONTROL_INTERROGATE。 TService.Controller 可能会发布它。如果是这种情况,检查 hwnd 将无济于事。
标签: multithreading delphi delphi-xe4 getmessage