Solved

D5 NT Services & Thread messages

Posted on 2000-03-08
12
305 Views
Last Modified: 2012-05-04
I have written an NT service in D5 which spawns multiple threads to perform various tasks and generally all works fine.  

The main problem I have is posting a message back to the main service thread when each spawned thread is finished (terminated).  The code snippet is  below.

In the Terminate Method of the Thread I have :

procedure TSapSMUHourThread.Terminate ;
begin
  PostThreadMessage(TheService.ServiceThread.ThreadID,wm_ThreadDoneMsg,Self.ThreadID,0) ;
  inherited Terminate ;
end ;

In the Main service I have const & message handler declared as :

.
const
  wm_ThreadDoneMsg = wm_User + 8 ;
.
.
.
procedure TService_CDMS_CS.ThreadDone(var AMessage : TMessage); message ;
.
.

I have debugged this and this message handler is definitely NOT activated.

Does anyone have any ideas ??

thanks in advance.
0
Comment
Question by:nitdgrev
12 Comments
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2599406
Are you sure it isn't

procedure TService_CDMS_CS.ThreadDone(var AMessage : TMessage); message wm_ThreadDoneMsg;

in your code. If not, it should be!

Cheers,

Raymond.


0
 

Author Comment

by:nitdgrev
ID: 2599428
ooops!!! a typo!.

Yes it is as you suggest (note I should have TTheService instead of TService_CDMS_CS as well).  It should read :

procedure TTheService.ThreadDone(var AMessage : TMessage); message wm_ThreadDoneMsg;

I just failed to make the critical step or typing it out here! Sorry for the confusion.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2599482
Have you tried a different constant (like wm_user + 1234) in case the one you used has already been taken?

Cheers,

Raymond.
0
 

Expert Comment

by:brunohe
ID: 2600486
Might be a problem. I think Delphi is using itself some WM_USER + x Values for internal purposes. I know, that sounds really stupid, but I thought that's the way it is.

Try as rwilson said WM_USER + 1234...
0
 

Author Comment

by:nitdgrev
ID: 2602487
I have tried using some other values but still can't get it to work.  I will try a few more combinations but it is looking grim.

Is this the correct procedure to use (ie PostThreadMessage) when sending a message back to the main service thread?
0
 

Author Comment

by:nitdgrev
ID: 2602590
I have for the time being an alternative to using messages which is working fine.

Instead of creating a message I have written an OnTerminate event handler for the Thread in question.  As far as I can tell this will be invoked in much the same way as the ThreadDone message handler.  

(I would still like to get the messages working however).

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 12

Expert Comment

by:rwilson032697
ID: 2602716
Is your main service thread the same as the main VCL thread?

if so you could just use PostMessage...

Cheers,

Raymond.
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2603864
This may, or may not, help:

PRB: PostThreadMessage Messages Lost When Posted to UI Thread
ID: Q183116

The information in this article applies to:

Microsoft Win32 Software Development Kit (SDK)


SYMPTOMS
Messages sent to a UI thread through PostThreadMessage are lost if the messages are posted while the user is manipulating a window owned by the thread. Messages might be lost if they are sent while the user moves or resizes the window or if the window is a modal dialog box.



CAUSE
When an UI thread is involved in modal behavior, the thread pumps messages in a message loop internal to the modal system rather than in the thread's main message loop. Messages that are posted to a window can still be dispatched to the window procedure of the target window, because the messages are associated with a window. However, thread messages need to be handled directly by the message loop, because they cannot be automatically dispatched elsewhere. Since the secondary message loop does not know about the thread message, it will be dropped.



RESOLUTION
Rather than using PostThreadMessage to post messages to a UI thread, use PostMessage to post messages to a window owned by that thread. Since messages directed to a window can be dispatched by a secondary message loop, the messages is still handled properly, even when the thread is not running in its primary message loop.

To use this method, the thread must create a window that lives throughout the period that it must receive messages, and the application sending the messages must have a handle to that window available.



STATUS
This behavior is by design.

0
 

Author Comment

by:nitdgrev
ID: 2606683
Thanks Raymond for all your suggestions.

While so far I haven't managed to solve this problem you do deserve some points.

The article does seem to make sense but how does this apply to an NT Service as there is no modal window ?  In regards to your comment about the VCL thread, I am not really certain, as I only assumed there was just the main service thread, no VCL thread?  If they are one & the same what handle do you use with PostMessage?  Am I on the right track do you think?



0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 2606794
I see now. Yes, your main service thread will be the main VCL thread.

PostThreadMessage will fail if there is no messages loop for the thread you are sending the message to. Can you see if it fails or not?

Read the help for PostThreadMessage, it has some more information regarding handling situations where the thread does not have a message loop.

Cheers,

Raymond.
0
 
LVL 1

Accepted Solution

by:
aldyn earned 300 total points
ID: 2607669
Your problem is caused by manner in which service thread processes messages. Look into svcmgr unit and search for PeekMessage calls (there are two only). Look on the second one. It takes messages from the thread's message queue and processes it. Note that if the hwnd parameter is 0 (it is your case because you send message to thread, not to window) then this messages will be processes in special manner. Namely it will be treated as a service control message. In your case it will result to DoCustomControl call with one parameter only. Other information from your message will be lost. The solution is simple enough: you will have to create a window (look how TTimer component creates window to receive WM_TIMER for example, you can use the same code with minimum changes)
and then you will be able to send messages to it. Let me know if you need a ready-to-use code.
0
 

Author Comment

by:nitdgrev
ID: 2610272
Thanks Aldyn and rwilson.  This has rectified the problem.  Note all help has been appreciated.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now