Can a Windows Service take hours to shutdown gracefully?
Asked Answered
K

3

8

We have a .NET Windows service that shovels a lot of highly critical data from A to B in a transactional manner. We also need to make sure that all external compontents used in the service are unallocated correctly and everything cleaned up before shutting down the service itself. This can take hours! The reason for this is that the service needs to wait on an external component's callback, which arrives 2, 3, or 4 hours later.

  1. is it possible for Windows to wait so long for a service to shutdown gracefully?
  2. are there options in a service where I can dictate what happens when the service is being shutdown by the operating system, e.g. prevent the shutdown altogether?
  3. also, as another scenario, what happens if the server needs to reboot? Can it wait hours for the service?
  4. Is there a limit on how long the OS will wait on the service before killing it?
Khalilahkhalin answered 16/9, 2011 at 6:42 Comment(1)
you forgot: 5. Is there a limit on how long a person will wait for that machine to shut down properly, before just pulling the plug?Competence
N
9

You can use CanStop, CanShutdown, CanHandlePowerEvent to be notified when the computer is shutting down and respond adequately.

Use the ServiceBase.RequestAdditionalTime method to request additional time to terminate your thread:

protected override void OnShutdown() 
{
    base.RequestAdditionalTime(MaxTimeout);
    serviceCore.OnShutdown();
    Stop(); 
}

If your OnShutdown() blocks for longer than 20 seconds (default value stored in the registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WaitToKillServiceTimeout), your service will be marked as unresponsive and killed.

There is a good blog post from the BCL team on that subject that I recommend.

Nanceynanchang answered 16/9, 2011 at 7:40 Comment(1)
Calling RequestAdditionalTime within OnShutdown will cause an InvalidOperationException.Stillage
A
4

Yes a service can stall shutdown until it completes, but should it? There are timeout values in the registry for this, what's the OS?

I think you need to decouple the callback from the other component, or buffer data to disk and send in smaller fragments. What happens in a powercut? Or if someone gets fed up waiting and switches off?

If the data is critical manage it outside of memory, and make the process restartable. This will solve your lengthly shutdown process. Likewise a way to poll the component for progress, takes away the dependency on blocking.

Annates answered 16/9, 2011 at 6:52 Comment(2)
Yes the data is critical in a sense. This is an enterprise level application where huge amounts of data are being moved, parsed, and indexed. The problem is that the component works slowly. There can be up to 20,000 callbacks waiting to happen at any given time, which is partly why it takes so long. Polling is not an option as its API doesn't allow us to.Khalilahkhalin
That's messed up, surely each call doesn't take several hours? Can you use smaller batches, and distribute calls across multiple machines?Annates
V
1

You can not use RequestAdditionalTime(MaxTimeout) inside OnShutdown() ...

Vassalize answered 25/9, 2013 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.