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

如何让Windows在.NET服务故障时自动重启该服务

解决方案

核心问题是:当BackgroundService在await后抛出未处理异常时,.NET Host会以零退出码优雅停止进程,Windows服务管理器将其判定为正常停止,不会触发sc failure配置的重启。要让Windows自动重启,必须让进程以非零退出码终止。

方法一:捕获BackgroundService异常并强制非零退出

步骤1:在Host启动时订阅停止事件

在Main函数中,构建Host后订阅ApplicationStopped事件,检测是否因未处理异常导致停止,若为异常则强制进程退出并返回非零码:

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services =>
    {
        services.AddHostedService<MyHostedService>();
    })
    .Build();

// 监听服务停止事件
host.Services.GetRequiredService<IHostApplicationLifetime>().ApplicationStopped.Register(() =>
{
    var myService = host.Services.GetService<MyHostedService>();
    if (myService?.UnhandledException != null)
    {
        // 非零退出码触发Windows服务重启
        Environment.Exit(1);
    }
});

await host.RunAsync();

步骤2:在BackgroundService中保存未处理异常

修改你的MyHostedService类,将未捕获的异常保存到公共属性中:

public class MyHostedService : BackgroundService
{
    public Exception UnhandledException { get; private set; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        try
        {
            // 你的业务逻辑(包含第三方库调用和await操作)
            while (!stoppingToken.IsCancellationRequested)
            {
                await ThirdPartyLibrary.BuggyMethodAsync();
                await Task.Delay(5000, stoppingToken);
            }
        }
        catch (Exception ex)
        {
            UnhandledException = ex;
            // 抛出异常让Host触发停止流程
            throw;
        }
    }
}

方法二:异常发生时直接强制退出进程

如果不需要Host完成优雅清理,可在BackgroundService捕获异常后直接调用Environment.Exit(1)终止进程:

public class MyHostedService : BackgroundService
{
    private readonly ILogger<MyHostedService> _logger;

    public MyHostedService(ILogger<MyHostedService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await ThirdPartyLibrary.BuggyMethodAsync();
                await Task.Delay(5000, stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "第三方库触发Bug,即将终止进程");
                // 直接退出进程,返回非零码
                Environment.Exit(1);
            }
        }
    }
}

验证sc配置正确性

确保你的故障重启配置命令语法正确(注意reset=后必须有空格):

sc failure "MyService" reset= 30 actions= restart/5000

该配置表示:30秒内无故障则重置故障计数,故障后5秒自动重启服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:48:11