Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

ServiceStop doesn't execute!!

Posted on 2003-12-03
26
Medium Priority
?
367 Views
Last Modified: 2010-04-05
Hello everybody

I built a Service with Delphi5.
In this service, I create a TTimer at runtime and this TTimer, in the OnTimer event does some job.
My problem is that if I try to stop the service when the Job is running, the ServiceStop event handler doesn't exec. It execs at the end of the job. If I stop the service while the timer is waiting, the ServiceStop eventhandler runs immediately.
What can I do?

Thanks to everybody!!!

Roberto
0
Comment
Question by:roburobe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 4
  • 4
  • +3
26 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9866336
drop some application.processmessages-lines
into your onTimer-event

just a guess

meikl ;-)
0
 
LVL 23

Expert Comment

by:Ferruccio Accalai
ID: 9866683
Well, meikl suggestion is the more easy and it should work good.
BTW, in a Service application, i'd create a TThread instead of using a TTimer, and let do the job by the TThread...

F68 ;-)
0
 
LVL 2

Expert Comment

by:classmate
ID: 9866722
listening...

meikl:
>drop some application.processmessages-lines...

TServiceApplication does not have a processmessages method in my delphi edition (D6)


0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:roburobe
ID: 9866779
classmate is right. a TService hasn't a ProcessMessages method.
I can write Service.ServiceThread.ProcessRequests but is it the same thing?

Thanks
0
 
LVL 6

Expert Comment

by:bpana
ID: 9866865
hi,

being a service application you cannot use application.processmessages.

When you stop the service, I suppose that it sends a message to your service to stop. I suppose that you have to intercept that message into your code, and exit the curent procedure.

Bogdan
0
 

Author Comment

by:roburobe
ID: 9866951
And what about creating another timer that makes Service.ServiceThread.ProcessRequests every 1/2 second?
0
 

Author Comment

by:roburobe
ID: 9866956
I already done that timer but it doesn't work..... :-(
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 9866976
>TServiceApplication does not have a processmessages method
ooops, sorry, not thought on that, its a service ;-)
0
 
LVL 6

Expert Comment

by:bpana
ID: 9866990
normally, you should use the onExecute event, which should look like this:

procedure TService1.ServiceExecute(Sender: TService);
begin
  // init...
 while not Terminated do
    ServiceThread.ProcessRequests(True);// wait for termination
  // exit...
end;

Bogdan
0
 
LVL 17

Expert Comment

by:geobul
ID: 9874916
Hi,

Try this: add lines in your OnTimer event like:

procedure TService1.Timer1Timer(Sender: TObject);
var i: integer;
begin
 if not Terminated then begin
   // one interruptable part of the code
 end else exit;
 if not Terminated then begin
   // another interruptable part of the code
 end else exit;
 // etc.
 // or you have a loop
 for i := 0 to 1000000 do begin
   if not Terminated then begin
     // the loop body
   end else exit;
 end;
end;

Regards, Geo
0
 

Author Comment

by:roburobe
ID: 9875307
Geo, this would be a nice solution. My problem is that in my OnTimer Event I call a procedure and that procedure calls many other procs in a structured mode. So I can't split the code.
I think one solution should be Ferruccio68's one. But before beginning such a transformation, I'd like to wait some more.

Thank you very much
0
 
LVL 17

Expert Comment

by:geobul
ID: 9875375
I don't think that moving your procedure call from the timer into a thread will solve your problem. It will simply move the termination problem in the thread and you'll have to find a way of terminating that thread. You'll need to divide your code in parts in that case also and to check for TThread.Terminated instead. Please, correct me if I'm wrong.
0
 

Author Comment

by:roburobe
ID: 9875440
Could be. the TTimer has his own thread so it should be the same thing.....

But in my code I have a point that is passed frequently. There I added the ckeck for Terminated but without results. I will try again payin' more attention.

Thank you very much.

Roberto
0
 

Author Comment

by:roburobe
ID: 9875447
Ferruccio68, what do you think about it?
0
 
LVL 23

Assisted Solution

by:Ferruccio Accalai
Ferruccio Accalai earned 750 total points
ID: 9899831
-> My problem is that in my OnTimer Event I call a procedure and that procedure calls many other procs in a structured mode. So I can't split the code.

well i think the difference between TTimer and TThread is this:

In Ontimer let's say you call DoProcerdures where DoProcedures is about

procedure DoProcedures;
begin
   DoFirstProc;
   DoSecondProc;
   DoThirdProc;
   etc...etc...
end;

So in your ontimer you must wait the whole execution of DoProcedures....

Using a TThread you can skip the DOProcedures one and let do the job by it like;

procedure TMyThrade.Execute;
begin
  while not Terminated do
  begin
   DoFirstProc;
   DoSecondProc;
   DoThirdProc;
   etc...etc...
  end;
end;
This means that the check for Terminated is done at the end of every single procedure....
BTW i was meaning that working in a Service i usually prefere to put my biggest procedures into threads so i can pass the Service stop into the thread directly and terminate the active thread at that time...

Note that using several threads could consume CPU times...but can give you the possibility of let execute Threads also if one thread is performing and waiting a slow execution...

F68 ;-)



0
 
LVL 6

Expert Comment

by:bpana
ID: 9899940
roburobe,

btw, why do you use a windows servcice for this task?

as i suppose, a Windows Service should provide its service (services) to other applications.

using a timer in a windows service is like making a formless application and schedule it.

just curious ...

Bogdan
0
 
LVL 17

Accepted Solution

by:
geobul earned 750 total points
ID: 9911046
Hi,

I'm sorry for saying that but you must explicitly check the Terminated property before every procedure in order to get it stopped. Just as I said that before:

procedure TMyThrade.Execute;
begin
  while not Terminated do
  begin
    if not Terminated then DoFirstProc;
    if not Terminated then DoSecondProc;
    if not Terminated then DoThirdProc;
    etc...etc...
  end;
end;

You may check that the thread's terminated status has been checked once only in a loop of the type:

while not Terminated do        // here is the check only and the body is interruptable !!!
  begin
   DoFirstProc;
   DoSecondProc;
   DoThirdProc;
   etc...etc...
  end;

using the example below. Start the thread and press Stop button after 'Line 1'. The thread will show all five lines before it gets terminated:

type
  TForm1 = class(TForm)
    re: TRichEdit;
    btnCreateThread: TButton;
    btnTerminateThread: TButton;
    procedure btnTerminateThreadClick(Sender: TObject);
    procedure btnCreateThreadClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TTransactionThread = class(TThread)
    procedure Execute; override;
    procedure Oops;
  private
    c: string;
  end;

var
  Form1: TForm1;
  TransactionThread: TTransactionThread;

implementation

{$R *.DFM}

procedure TTransactionThread.Oops;
begin
  Form1.re.Lines.Add('Line '+c);
end;

procedure TTransactionThread.Execute;
begin
 while (not terminated) do begin
   c := '1';
   Synchronize(Oops);
   sleep(1000);
   c := '2';
   Synchronize(Oops);
   sleep(1000);
   c := '3';
   Synchronize(Oops);
   sleep(1000);
   c := '4';
   Synchronize(Oops);
   sleep(1000);
   c := '5';
   Synchronize(Oops);
   sleep(1000);
 end;
end;

procedure TForm1.btnTerminateThreadClick(Sender: TObject);
begin
  TransactionThread.Terminate;
end;

procedure TForm1.btnCreateThreadClick(Sender: TObject);
begin
  TransactionThread := TTransactionThread.Create(true);
  TransactionThread.FreeOnTerminate := true;
  TransactionThread.Resume;
end;

end.

Regards, Geo
0
 
LVL 23

Expert Comment

by:Ferruccio Accalai
ID: 9911380
geobul you're absolutelly right....my mistake in my previous post (it came just from head :) BTW your example is quit near to what i was meaining...

F68 ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10711530
just wondering about the accepted answer with 0 (zero) points?
0
 
LVL 23

Expert Comment

by:Ferruccio Accalai
ID: 10711623
Hi meikl, i've received an assisted with B grade for 750 total points and i guess that's the same for Geo....
I don't know about the sense of accepting and assisting used by the questioner here, but if for some mistake you've to reopen the question, as you're the PE, for me it's ok :)

F68 ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 10711647
just waiting for the questioner's intention.

btw.
i'm not worry about 0 pts., still wondering,
so i may ask the questioner, if the grading is so
ok as he/she meant .

meikl ;-)
0
 

Author Comment

by:roburobe
ID: 10711681
Hello,

I made a mistake... I didn't click any "radio button" fro the accepted answer and then EE assigned meikl's answer to be my accepted answer. I intended to spit points between F68 and Geobul with Geobul to be the answerer.
So:
1) please, don't worry... I'm not an expert like you....
2) can tuo help me solve this situation???

Thank you very much!!!

Roberto
0
 

Author Comment

by:roburobe
ID: 10711803
If you can, please, so I can adjust my solution.....

thank you very much!!!!

Roberto
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

660 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