You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Topshelf阻止Windows Service停止原理及.NET 7自定义实现失效排查

.NET 7 Windows Service中阻止Stop命令失效问题排查

我需要在.NET 7 Windows Service中实现阻止Stop命令的行为:

  • 参考Topshelf的实现逻辑:其服务宿主继承自ServiceBase,在重写的OnStop方法中,若_serviceHandle.Stop(this)返回false,则抛出异常并设置ExitCode = 1064后重新抛出。
  • 查看ServiceBase的DeferredStop方法可知:调用OnStop时若抛出异常,会将服务状态重置为之前的运行状态并重新抛出异常。

但我基于WindowsServiceLifetime(该类继承自ServiceBase)编写的自定义类CancelableWindowsServiceLifetime,逻辑与Topshelf类似,却出现OnStop中抛出异常后服务仍会停止的问题。对比.NET 7版本的ServiceBase实现未发现明显差异,请问这是什么原因?

需求说明

当有作业运行时阻止服务停止;若在滑动窗口内收到足够多次停止请求,则允许停止并终止运行中的作业。

相关代码

Topshelf的OnStop实现

public class WindowsServiceHost :
    ServiceBase,
    Host,
    HostControl
{
    // 省略其他代码

    protected override void OnStop()
    {
        try
        {
            _log.Info("[Topshelf] Stopping");

            if (!_serviceHandle.Stop(this))
                throw new TopshelfException("The service did not stop successfully (return false).");

            _log.Info("[Topshelf] Stopped");
        }
        catch (Exception ex)
        {
            _settings.ExceptionCallback?.Invoke(ex);

            _log.Fatal("The service did not shut down gracefully", ex);
            ExitCode = (int) TopshelfExitCode.ServiceControlRequestFailed;
            throw;
        }
    }
}

ServiceBase的DeferredStop方法实现

private unsafe void DeferredStop () 
{
    fixed (NativeMethods.SERVICE_STATUS *pStatus = &status) 
    {
        int previousState = status.currentState;

        status.checkPoint = 0;
        status.waitHint = 0;
        status.currentState = NativeMethods.STATE_STOP_PENDING;
        NativeMethods.SetServiceStatus (statusHandle, pStatus);
        try 
        {
            OnStop();

            // 省略其他代码...
        }
        catch (Exception e) 
        {
            status.currentState = previousState;
            NativeMethods.SetServiceStatus (statusHandle, pStatus);
            WriteEventLogEntry (Res.GetString (Res.StopFailed, e.ToString ()), EventLogEntryType.Error);
            throw; 
        }
    } // fixed
} // DeferredStop

自定义CancelableWindowsServiceLifetime实现

[System.Runtime.Versioning.SupportedOSPlatform( "windows" )]
public class CancelableWindowsServiceLifetime : Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceLifetime
{
    private readonly ICancelableBackgroundService cancelableBackgroundService;

    public CancelableWindowsServiceLifetime( IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, ICancelableBackgroundService cancelableBackgroundService, ILoggerFactory loggerFactory, IOptions<HostOptions> optionsAccessor )
        : this( environment, applicationLifetime, cancelableBackgroundService, loggerFactory, optionsAccessor, Options.Create( new WindowsServiceLifetimeOptions() ) )
    {
    }

    public CancelableWindowsServiceLifetime( IHostEnvironment environment, IHostApplicationLifetime applicationLifetime, ICancelableBackgroundService cancelableBackgroundService, ILoggerFactory loggerFactory, IOptions<HostOptions> optionsAccessor, IOptions<WindowsServiceLifetimeOptions> windowsServiceOptionsAccessor )
        : base( environment, applicationLifetime, loggerFactory, optionsAccessor, windowsServiceOptionsAccessor )
    {
        this.cancelableBackgroundService = cancelableBackgroundService;
    }

    protected override void OnStop()
    {
        if ( !cancelableBackgroundService.CanStop() )
        {
            ExitCode = 1064; // ERROR_EXCEPTION_IN_SERVICE

            throw new ApplicationException( $"Unable to stop service at this time." );
        }

        base.OnStop();
    }
}

内容的提问来源于stack exchange,提问作者Terry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 23:37:01