#1 2017-03-16 13:15:51

StxLog
Member
From: France
Registered: 2015-09-14
Posts: 58

Synchronize in service

Hello,
Within my server I have to launch one custom TThread for doing some non-critical action in background. Its execution is generally around 2 min, then stop and call DoTerminate to notify server he can do some other action. In a console app, everything is working fine with the SynCommons.ConsoleWaitForEnterKey procedure which call CheckSynchronize. But when i'm using my server as Windows service, with TServiceSingle, there is no CheckSynchronize call.

What would be the best way to implement a similar logic to call CheckSynchronize in services please?

Offline

#2 2017-03-16 14:45:26

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Synchronize in service

You should not have to wait for anything in services.

CheckSynchronize is not to be called in services, which do not have a Windows message loop.

Offline

#3 2017-03-16 15:11:39

StxLog
Member
From: France
Registered: 2015-09-14
Posts: 58

Re: Synchronize in service

Thanks for reply.

Maybe there is something I do not understand (it is very likely, i'm not used to services), but my service isn't waiting while my secondary thread is running, I just want to execute one method when thread is done.

My purpose is to execute some long procedure in background, and when it's finished notify users by emails, but I can't send the email from my background task for various reason. Maybe I could achieve this with TSynBackgroundThread* classes? Haven't looked at it yet, as my threaded class is already tested.

Offline

#4 2017-03-16 19:39:51

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Synchronize in service

How do you communicate between the threads?

Offline

#5 2017-03-17 08:23:38

StxLog
Member
From: France
Registered: 2015-09-14
Posts: 58

Re: Synchronize in service

Right now, simply with the OnTerminate event of the thread. They do not talk to each other while thread execution. I just need to briefly reenter in the main thread when execution is over.

Offline

#6 2017-03-17 20:32:19

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Synchronize in service

There is no Windows message loop in a service, so you can't send a message to the "main loop", which does not exist in a service...

Offline

#7 2017-03-17 23:56:09

igors233
Member
Registered: 2012-09-10
Posts: 241

Re: Synchronize in service

Do you need to pass some information to the mainThread or just a notification that job is finished? If you only need notification you can use Events for that.
If you need to pass some information as well, perhaps PostThreadMessage would work (it's not clear if it works in services) or you can use named pipes, memory mapped files or sockets.

Offline

#8 2017-03-18 08:05:27

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Synchronize in service

The is no such thing as a "main thread" in a Windows service, I'm afraid, since there is no GUI thread.
So PostThreadMessage won't help.

You can use named pipes or socket.
But calling one thread method from another is the way to go, in your case, I'm quite sure.

Offline

#9 2017-03-18 17:23:48

George
Member
Registered: 2016-04-05
Posts: 142

Re: Synchronize in service

Offline

#10 2017-03-20 11:31:46

George
Member
Registered: 2016-04-05
Posts: 142

Re: Synchronize in service

http://stackoverflow.com/questions/2245 … ws-service

OmniThreadLibrary in a service works just fine. There's an example in the repo showing that.

Last edited by George (2017-03-20 11:33:54)

Offline

#11 2017-03-20 11:45:26

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Synchronize in service

Perhaps OTL here is like using a sledgehammer to crack a nut in this context...

Server notification could be just done by executing a server method from the finished thread!

Offline

#12 2017-03-20 16:11:14

StxLog
Member
From: France
Registered: 2015-09-14
Posts: 58

Re: Synchronize in service

Thanks all for reply and trying to help !

@igors233: I needed to pass some information contained within my thread yes.

Yes indeed, I wanted to avoid using OTL as what I wanted to do was quite "simple" (and a lot of work with OTL just for this).

So what i've done in the end is override my DoTerminate method from my TThread like that:

procedure TMyThread.DoTerminate;
begin
  if fByPassSynchronize then
  begin
    if Assigned(OnTerminate) then OnTerminate(Self);
  end else
    inherited;
end;

So when i'm within a service I juste have to set BypassSynchronize := true and my OnTerminate event is well fired at the end.
I've just added a locker to protect shared ressource in the onterminate method just in case,

I will run some more tests as I didn't had time today, but I think this will be enough for my purpose. If not I will make a server method and initiate a client to call it.

Thanks for taking the time even if this isn't directly related to mORMot ; )

Offline

#13 2017-03-20 18:58:19

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,700
Website

Re: Synchronize in service

You could call it from the end of the Execute method.

Or you may have used a TSynThread which fires the KnTetminate event in the thread context.

Offline

Board footer

Powered by FluxBB