我已经实现了一个启动几个工作线程的Windows XP服务应用程序。 从其中一个线程我需要将自定义消息发送回服务。 我该怎么做?
答案 0 :(得分:1)
一种选择是使用OmniThreadLibrary(例如,阅读this blog post。)
答案 1 :(得分:1)
感谢您的帮助。以下是我解决问题的方法:
在Service类定义中:
WHandle: HWND;
protected
procedure HandleServiceMessage(var Msg: TMessage); virtual;
在ServiceExecute方法中:
WHandle := AllocateHWnd(HandleServiceMessage);
MyThread := TMyThread.Create(true);
MyThread.HndMain := WHandle;
MyThread.Resume;
while not Terminated do ServiceThread.ProcessRequests(True);
DeallocateHWnd(WHandle);
end;
在ServiceStop方法中:
MyThread.Terminate;
处理消息的方法:
procedure TMessageService.HandleServiceMessage(var Msg : TMessage);
var
Handled: Boolean;
begin
Handled := True;
if Msg.Msg = WM_MYMESSAGE then
Beep
else
Handled := False;
if Handled then
Msg.Result := 0
else
Msg.Result := DefWindowProc(WHandle, Msg.Msg, Msg.WParam, Msg.LParam);
end;
在MyThread.Execute方法中:
PostMessage(HndMain,WM_MYMESSAGE,0,0);
它的工作正常。
答案 2 :(得分:0)
我同意TOndrej认为共享对象应该足够了。
另一方面,您可以使用我的IPC(Cromis IPC),它在内部服务中运行良好。它易于使用,面向消息,因此您无需知道命名管道如何工作且速度非常快。服务器部分也使用线程池,因此无需等待处理。您可以使用即发即弃的场景。
或者,如果你认为一点点重新设计是可以的,你可以尝试OmniThreadLibrary,它已经内置了所有的消息,并且是为这样的任务而做的。
修改强>:
好吧可能最简洁的方法,没有任何重新设置就是拥有一个受关键部分保护的公共对象列表。工作线程正在添加需要在列表中处理的对象。当添加和对象时,工作线程发出一个事件信号。然后你有一个对象处理线程,它等待WaitForSingleObject用于此事件。一旦将某些内容添加到列表中,就会发出事件信号,处理线程只处理它在列表中找到的所有对象。然后它再次等待。您需要做的就是保护对公共列表的访问。
简化代码如下所示:
WORKER THREAD
ObjectList.Add(MessageObject);
SetEvent(FEvent);
处理线程
while not Terminated do
begin
WaitForSingleObjest(FEvent, INFINITE);
// process all the objects
end;
答案 3 :(得分:0)
创建仅限消息的窗口:
procedure TMyService.MessageQueueDispatch(var Message: TMessage);
begin
Dispatch(Message); //Delphi default dispatcher for TMyService
end;
procedure TMyService.SomeKindOfOnCreate;
begin
MessageQueue := AllocateHWnd(MessageQueueDispatch);
end;
毁:
procedure TMyService.SomeKindOfDestroy;
begin
CloseHandle(MessageQueue);
end;
现在您可以像处理表单消息一样处理消息:
TMyService = class(TService)
...
protected
procedure HandleMyMessage(var msg: TMsg); message WM_MY_MESSAGE;
end;
Delphi Dispatch()处理程序将负责调用该函数。