2010-10-08 107 views
0

我已經實現了一個啓動了幾個工作線程的windows xp服務應用程序。 從我需要發送自定義消息回服務的線程之一。 我該怎麼做?我如何將自定義消息發送到Windows服務?

+0

您的工作線程是您的服務應用程序的一部分,因此您不清楚您要做什麼。我的印象是,你需要在線程之間傳遞一些數據,這可以通過簡單地保持對數據結構的引用並鎖定線程安全來完成。根據您的意圖,主服務線程可能更容易輪詢工作線程的狀態。你能提供更多細節嗎? – 2010-10-08 11:32:56

+0

我會盡力解釋更好。我的服務應用程序在其OnStart事件中創建兩個線程。它還創建一個對象列表(對象有自己的功能和屬性)。現在,兩個線程之一輪詢串行端口以獲取新數據,並且需要將這些數據(或超時)發送給對象列表中的一個對象,但是我需要在不中斷其執行的情況下執行此操作。所以,當串行端口上的數據可用時,我想將消息發佈到主服務線程。這個主要的服務線程可以將數據發送給對象。 – zoomz 2010-10-08 11:45:00

+0

我明白,一個可能的解決方案是在服務類中創建一個僅消息窗口,但我不完全知道如何去做。 – zoomz 2010-10-08 11:52:16

回答

1

感謝您的幫助。這裏是我解決了這個問題:

在服務類定義:

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); 

它的工作就好了。

0

我同意TOndrej共享對象應該是足夠的。

另一方面,您可以使用我的IPC(Cromis IPC),它在服務內部工作得很好。它很容易使用,面向消息,所以你不需要知道命名管道的工作方式和速度。服務器部分也使用線程池,因此不需要等待某些內容被處理。您可以使用消防和忘記方案。

或者如果您認爲有一點重新設計是可以的,您可以嘗試OmniThreadLibrary,它具有已經構建的所有消息傳遞,並且用於執行這樣的任務。

編輯

好了可能是最清晰的路要走,沒有任何redesing是具有由臨界區保護的通用對象列表。工作線程正在添加需要在列表中處理的對象。當添加對象時,工作線程發出事件信號。然後你有一個對象處理線程正在等待WaitForSingleObject這個事件。只要有東西添加到列表中,事件就會發出信號,處理線程會處理它在列表中找到的所有對象。然後它再次等待。您只需保護對公共列表的訪問權限即可。

簡化代碼應該是這樣的:

工作者線程

ObjectList.Add(MessageObject); 
SetEvent(FEvent); 

處理線程

while not Terminated do 
begin 
    WaitForSingleObjest(FEvent, INFINITE); 
    // process all the objects 
end; 
+0

我沒有時間重新設計。除了那部分,整個應用程序工作得很好。我只需要從主服務線程運行內部對象函數,而不是從工作線程運行。 – zoomz 2010-10-08 12:18:17

+0

然後,只需使用我的IPC解決方案或實施我在我的編輯中建議的內容。 – Runner 2010-10-08 12:41:51

+0

通過這種方法,我最好創建另一個線程來查看消息,並將它們分派給正確的對象。 – zoomz 2010-10-08 12:59:12

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; 

德爾福調度()處理程序將調用函數的照顧。

+0

AlloocateHWnd()不是線程安全的,不應該在主線程之外調用。 TService改爲在自己的工作線程中運行。 – 2010-10-08 18:01:41

相關問題