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

.NET 6 Windows服务停止时写入两条重复事件日志问题

问题背景

该问题不会引发任何运行故障,仅系统事件日志表现不符合预期,相关信息如下:

  • 实现基础:基于.NET 6参照微软官方Windows服务开发指南编写,当前版本清空了ExecuteAsync方法内所有业务代码,服务暂不执行任何实际业务逻辑。
  • 异常现象:停止服务时,系统事件日志会写入2条时间完全一致、内容完全重复的服务停止事件,对应截图如下:
    服务重复停止事件截图
  • 项目核心代码:
    Program.cs
    namespace WindowsServiceSandbox
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var host = Host.CreateDefaultBuilder(args)
                    .UseWindowsService(options => {options.ServiceName = "Test Windows Service";})
                    .ConfigureServices(services => {services.AddHostedService<Worker>();})
                    .Build();
    
                host.Run();
            }
        }
    }
    
    Worker.cs
    namespace WindowsServiceSandbox
    {
        public class Worker : BackgroundService
        {
            private readonly ILogger<Worker> _logger;
    
            public Worker(ILogger<Worker> logger)
            {
                _logger = logger;
            }
    
            protected override Task ExecuteAsync(CancellationToken stoppingToken)
            {
                return Task.CompletedTask;
            }
        }
    }
    
原因分析

重复日志的根源是ExecuteAsync实现不符合BackgroundService的生命周期设计逻辑:

  • 直接返回Task.CompletedTask意味着ExecuteAsync在服务启动完成的瞬间就同步执行结束。而BackgroundService的默认逻辑是:只要ExecuteAsync执行完成,就会自动触发主机停止流程,此时UseWindowsService内置的日志模块会写入第一条服务停止事件。
  • 这时候服务本身还处于运行状态,后续手动触发服务停止操作时,Windows服务控制管理器会走标准的服务停止流程,日志模块会再写入一条完全相同的停止事件,最终出现两条同时间、同内容的重复记录。
    本质是服务启动瞬间就因ExecuteAsync直接退出,隐式走完了一轮停止流程打出第一条日志,和后续手动触发的显式停止流程打出的日志重合,不是日志组件或者系统服务的bug。
修复方案

哪怕暂时没有业务逻辑需要执行,也要让ExecuteAsync持续等待到收到服务停止信号后再退出,不能直接返回完成状态。将Worker.cs中的ExecuteAsync方法修改为如下写法即可:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    try
    {
        // 无限等待,直到服务收到停止信号触发令牌取消
        await Task.Delay(Timeout.Infinite, stoppingToken);
    }
    catch (OperationCanceledException)
    {
        // 停止时抛出取消异常属于预期行为,无需额外处理
    }
}

修改后服务启动后会正常驻留,不会在启动阶段提前触发隐式停止流程,停止服务时只会生成1条停止事件日志,表现符合预期。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:48:17