Clean Service Shutdown

G

Guest

Hello-

I'm working with a .NET windows service that can potentially take up to
10 minutes to shutdown. I would like to make it so that SCM doesn't
timeout before the service actually stops, but unfortunately have not
found a method that works.

I've tried using ServiceBase.RequestAdditionalTime in several ways:
1) Start the shutdown process in a seperate thread in OnStop and keep
requesting more time with ServiceBase.RequestAdditionalTime. (Doesn't
appear to work)

2) In OnStop use ServiceBase.RequestAdditionalTime to request 10
minutes, then start the shutdown (a blocking call). (Doesn't appear to
work).

3) Have the program generate an event during shutdown which causes the
service to RequestAdditionalTime. (Doesn't appear to work).

Does anybody have any suggestions? Is there something I can do to
configure SCM so that it respects the request for additional time? Is
there a better method than ServiceBase.RequestAdditionalTime?

Thanks,
eroc.
 
B

Brian Gideon

eroc,

What is the service doing that can take up to 10 minutes? If you abort
this long operation will it put your system in an inconsistent state?

Brian
 
E

ericrahm

Brian-

We need to dump a ton of accumulated data into a database, so
unfortunately aborting is not an option.

Thanks,
eroc.
 
E

ericrahm

Steve-

I've noticed that the process does in fact stick around after SCM times
out, so the pushing out of data to our DB does happen -- that's not
really what I'm concerned about.

The problem is that SCM gives up before it's actually finished. It
seems that RequestAdditionalTime should take care of the timeout, but
doesn't actually work. This causes problems for us because we had
intended to use some scripts to bring down our service occasionally for
maintenance and we get in an inconsistent state when "net stop service"
returns too early.

Thanks,
eroc.
 
B

Brian Gideon

eroc,

Can you change your script to wait until the service has stopped? I've
done this before using the following syntax.

REM ** Begin Script **
REM ** Watch for line wraps in the script due to usenet posting **

:STOP

for /f "Tokens=1-2* Delims=: " %%a in ('sc query YourService^|FIND
"STATE"') do set STATE=%%b

if "%STATE%" EQU "4 " echo Stopping YourService service... & sc stop
YourService

:WAIT_FOR_STOP

for /f "Tokens=1-2* Delims=: " %%a in ('sc query YourService^|FIND
"STATE"') do set STATE=%%b

if "%STATE%" EQU "3 " echo Waiting for YourService service to stop... &
sleep 1 & goto WAIT_FOR_STOP

REM ** End Script **

It's a little cryptic, but basically it uses the sc utility to query
the status of the service and sleeps 1 second if the status is equal to
3 (which I think is STOP_PENDING) and then checks again. Replace
YourService in the script with the actual name of your service. Of
course if you used a vbs script or something instead of a batch file it
would be much easier, but this is the best I could come up with in a
batch file.

The problem still remains when the box goes down. Windows will issue a
stop command to the service, but it won't wait forever before shutting
down. It will eventually kill the service. If the puts your database
in an inconsistent state then you have another problem to deal with.

Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top