Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 368
  • Last Modified:

ServiceStop doesn't execute!!

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
roburobe
Asked:
roburobe
  • 8
  • 4
  • 4
  • +3
2 Solutions
 
kretzschmarCommented:
drop some application.processmessages-lines
into your onTimer-event

just a guess

meikl ;-)
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
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
 
classmateCommented:
listening...

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

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


0
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.

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

Thanks
0
 
bpanaCommented:
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
 
roburobeAuthor Commented:
And what about creating another timer that makes Service.ServiceThread.ProcessRequests every 1/2 second?
0
 
roburobeAuthor Commented:
I already done that timer but it doesn't work..... :-(
0
 
kretzschmarCommented:
>TServiceApplication does not have a processmessages method
ooops, sorry, not thought on that, its a service ;-)
0
 
bpanaCommented:
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
 
geobulCommented:
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
 
roburobeAuthor Commented:
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
 
geobulCommented:
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
 
roburobeAuthor Commented:
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
 
roburobeAuthor Commented:
Ferruccio68, what do you think about it?
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
-> 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
 
bpanaCommented:
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
 
geobulCommented:
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
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
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
 
kretzschmarCommented:
just wondering about the accepted answer with 0 (zero) points?
0
 
Ferruccio AccalaiSenior developer, analyst and customer assistance Commented:
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
 
kretzschmarCommented:
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
 
roburobeAuthor Commented:
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
 
roburobeAuthor Commented:
If you can, please, so I can adjust my solution.....

thank you very much!!!!

Roberto
0

Featured Post

Industry Leaders: 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!

  • 8
  • 4
  • 4
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now