开发者

.NET windows service aborted during system shutdown

开发者 https://www.devze.com 2022-12-20 09:22 出处:网络
My windows service is a data server with substantial cache. During service OnStop I save the cache so that no data is lost. Saving cache may take several minutes so to prevent windows service manager

My windows service is a data server with substantial cache. During service OnStop I save the cache so that no data is lost. Saving cache may take several minutes so to prevent windows service manager from timeout I use SetServiceStatus Win32 callback:

this.serviceStatus.currentState = (int)State.SERVICE_STOP_PENDING;
this.serviceStatus.checkPoint = 1;
this.serviceStatus.waitHint = 60000;
SetServiceStatus(Process.GetCurrentProcess().Handle, ref this.serviceStatus);

That works fine.

I have also set CanShutdown to true and added OnShutdown so that service would be system shutdown proof. Here I effectively do the same thing as in OnStop:

protected override void OnShutdown()
{
    this.OnStop(); 
    base.OnShutdown();
}

That does not work too good. When system shuts down, when cache is being saved I get "The device is not ready". This suggests that Windows aborts service before it is done stopping / shutting down. Preventing that wi开发者_如何学Cth SetServiceStatus apparently does not work.

How do I get more time (delay reboot) to get saving done?

Any suggestions welcome.


The preferred way to handle this can be found in this article on the BCL Team's blog. The article includes a bit of background on how managed services interact with the SCM, which is important for understanding why the approach shown in the question is no longer recommended.

Simply put, ServiceBase now handles service state management for you and your code just needs to request additional time if required. Read the article for a few other good guidelines for writing SCM-friendly services in .NET.


Using ManualResetEvent might be the trick.


After some testing it looks that it was a problem with the system rather than with my service.


Another easy way, after hours of searching on how to include the setservicestatus method:

    protected override void OnStop()
    {
        stopTimer();
        m_run = false;
        while (m_queue.Count > 0)
            Thread.Sleep(500);
    }
0

精彩评论

暂无评论...
验证码 换一张
取 消