Windows service shutdown

T

tshad

I have a Windows Service that I need to put to sleep for about 10-20
minutes.

The problem is that if you try to shut it down during this time, it will
tell you that the service didn't respond in time and end up in a "Stopping"
state and there is nothing you can do until you reboot the system.

What I did to solve the problem was just set a flag in my Shutdown method
and set up a loop in my program to go to sleep for 1 minute at a time, wake
up and check the flag then go to sleep for another minute until the maximum
number of minutes have elapsed.

What I don't know is what is the duration of time that a service has to
shutdown before it gets that message, or is there a setting somewhere where
you can set it?

Thanks,

Tom
 
P

Peter Morris

Instead of calling Sleep(x) use AutoResetEvent.WaitOne(x, false).

This way it will sleep for x but wake up immediately if you set the event.
You can then call MyAutoResetEvent.Set() from your shutdown method and the
thread will awaken immediately.
 
P

Phil Wilson

I think this is what service pause is for, CanPauseAndContinue and the
OnPause event, assuming you have code somewhere to tell the service to
pause, and continue later.
 
T

tshad

Peter Duniho said:
[...]
What I don't know is what is the duration of time that a service has to
shutdown before it gets that message, or is there a setting somewhere
where
you can set it?

Rather than worrying about that specific duration, you should just fix the
service so that it doesn't become unresponsive while it's sleeping (why
you feel it necessary for it to sleep "for about 10-20 minutes" is hard to
understand too, but for the moment let's assume that's actually necessary
even though it doesn't seem quite right).
Because in this case it is a FileWatcher that is running through files and
processing them and depends on SQL Server. If Sql Server goes down
(maintenance, reboots, crashes etc), I want the Service to go to sleep for a
specified amount of time and then try again. If it is still down it will do
that again - each time sending a message that it is still getting a timeout.
I don't want it to be checking again right after it got the error over and
over again sending messages every 20 seconds.

I figure 10 minutes or so is a good duration.
From your description (it's impossible to know for sure without a
concise-but-complete code sample) in the thread that would normally
process messages for the service, you are calling something like
Thread.Sleep() with some long value. That, of course, causes the server
to fail to respond to _any_ message.

Which is why I changed the code to go to sleep for a minute, wake up and
check if the stop button was pressed. If not, it goes to sleep for another
minute until the maximum amount of minutes has gone by. If the stop button
was pressed, it exits the thread (after releasing the Mutex I am using).

Thanks,

Tom
 
T

tshad

Peter Morris said:
Instead of calling Sleep(x) use AutoResetEvent.WaitOne(x, false).

This way it will sleep for x but wake up immediately if you set the event.
You can then call MyAutoResetEvent.Set() from your shutdown method and the
thread will awaken immediately.

That sounds pretty good,

I'll try that.

Thanks,

Tom
 
J

JTC^..^

Because in this case it is a FileWatcher that is running through files  
and
processing them and depends on SQL Server.  If Sql Server goes down
(maintenance, reboots, crashes etc), I want the Service to go to sleep  
for a
specified amount of time and then try again.  If it is still down it  
will do
that again - each time sending a message that it is still getting a  
timeout.
I don't want it to be checking again right after it got the error over  
and
over again sending messages every 20 seconds.  [...]

But instead of making your service unresponsive, you should instead simply  
have it internally defer whatever work it would normally do, based on a  
timer.  There's no reason to block a thread for that.

Your current "sleep for a minute then check" is definitely not the way to 
go.  Even Peter M.'s suggestion is less than optimal because it assumes 
there's a thread somewhere that _can_ respond by setting the event  
handle.  It would be best to just not make the service unresponsive in the  
first place.

If it were orders of magnitude harder to do it the right way than the  
wrong way, I could see the lure of doing it the wrong way.  But it's not  
hard to set up a timer and include logic to cause normal processing to be 
suspended without actually blocking a thread.

Pete

Let the service handle exception by incrementing a counter each time
it fails. Report the exception only after a number of retries. Reset
the counter if it succeeds. For example the service will report the
exception only after 5 retries.

The down side to this is that you will not know if the service fails
regularly, but works after a couple of retries. So rather than
resetting the counter when it suceeds, the counter could be reset
after an hour. In other words, if fails 5 times within one hour you'll
be notified too.

Of course, the number of retries and timer duration it upto you.
 
P

Peter Morris

Your current "sleep for a minute then check" is definitely not the way to
go. Even Peter M.'s suggestion is less than optimal because it assumes
there's a thread somewhere that _can_ respond by setting the event
handle.

Seeing as this service sleeps for X seconds and then tries to process files
but needs to postpone that work for 10 minutes if SQL Server was unreachable
I see no reason why it should wake up every X seconds just to check if it
has been terminated. We know it should not process any files for another 10
minutes so the thread only needs to resume if it is told to terminate. In
which case we just need the worker running in a 2nd thread.
 
P

Peter Morris

Hi Peter
One of the most annoying things in an OS is software that isn't
responsive. It delays operations like shutting the software itself down,
or shutting down the operating system, for no good reason.

I agree. It should be responsive.

You seem to be taking offense to my commentary about your proposed
solution. I'm sorry if I offended you; I'm simply stating my opinion.

hehe. I honestly have no idea why you think I am offended :)

Your proposal is certainly better than what Tom's doing now. I just
happen to believe there's an even better approach that can be used.

As I have just written a similar service I'd be interested in reading what
it is :)
 

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