我正在开发一个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个线程,一个是使用不同消息号的计时器,并且在发生这种情况时不发送任何内容。
最佳答案
在TService
代码中,您可以找到以下代码:
const
CM_SERVICE_CONTROL_CODE = WM_USER + 1;
....
procedure TService.Controller(CtrlCode: DWord);
begin
PostThreadMessage(ServiceThread.ThreadID, CM_SERVICE_CONTROL_CODE, CtrlCode, 0);
if ServiceThread.Suspended then ServiceThread.Resume;
end;
因此,
TService
发送的消息号与您的消息相同。你怎么区分他们?好吧,你不能。从
WM_USER
的文档中:通常,这将用于发送到窗口的消息,并且消息的含义是特定于类的。当我阅读
TService
代码时,设计人员认为他们完全控制消息队列,并有权确定其私有(private)消息的含义。最终结果是,您不能使用WM_USER
范围内的线程消息,因为它们已被TService
类保留。您的主要选择:
RegisterWindowMessage
可确保消息ID唯一。 关于multithreading - GetMessage中的wparam值不是我所期望的(Delphi XE4),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28772011/