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

为何C#后台服务以服务运行失败,以可执行文件运行正常?

.NET Core Windows服务触发System.OperationCanceledException异常问题

我用C#开发了一个后台服务,上周部署到虚拟机,通过sc.exe create NameOfService binPath= blabla命令创建服务后运行正常,直到2023年2月13日(周日)23:58出现异常。直接运行.exe文件一切正常,但以服务形式启动就会触发以下异常:

Application: SE.Worker.SystemStatus.exe
CoreCLR Version: 4.700.20.11803
.NET Core Version: 3.1.3
Description: The process was terminated due to an unhandled exception.
Exception Info: System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowOperationCanceledException()
   at Microsoft.Extensions.Hosting.Internal.Host.StopAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.WaitForShutdownAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at SE.Worker.SystemStatus.Program.Main(String[] args) in D:\App\Solution\SE.Worker.SystemStatus\Program.cs:line 12

相关代码

Program.cs

public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();

public static IHostBuilder CreateHostBuilder(string[] args) =>
   Host.CreateDefaultBuilder(args).UseWindowsService()
       .ConfigureLogging(logging =>
       {
           logging.ClearProviders();
           logging.AddConsole();
           logging.AddEventLog();
       })
       // Essential to run this as a window service
       .ConfigureServices(configureServices);

private static void configureServices(HostBuilderContext context, IServiceCollection services)
{
    services.Configure<StatusConfig>(context.Configuration.GetSection("Status"));
    services.AddLogging();

    services.AddSingleton<IVersionProcess, SystemStatusProcess>();
    services.AddHostedService<SystemStatusWorker>();
}

SystemStatusWorker.cs

public class SystemStatusWorker : BackgroundService
{
    private readonly ISystemStatusProcess systemStatusProcess;
    private readonly ILogger<SystemStatusWorker> logger;

    public SystemStatusWorker(ISystemStatusProcess systemStatusProcess, ILogger<SystemStatusWorker> logger)
    {
        this.systemStatusProcess = systemStatusProcess;
        this.logger = logger;
    }
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            logger.LogInformation("SystemStatus Worker running at: {time}", DateTimeOffset.Now);
            await systemStatusProcess.GetSystemStatus();
        }
    }
}

可能的原因及解决方案

  1. 服务启动超时被系统终止
    Windows服务默认有30秒的启动超时限制,如果systemStatusProcess.GetSystemStatus()执行时间过长,或服务初始化耗时超过阈值,系统会强制终止服务并触发取消异常。
  • 解决:检查GetSystemStatus()是否存在长时间阻塞操作,优化代码确保异步执行;或修改注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control下的ServicesPipeTimeout值(单位毫秒,例如设为60000即60秒)调整超时时间。
  1. 未在业务方法中响应取消令牌
    虽然ExecuteAsync方法检查了stoppingToken,但GetSystemStatus()内部未处理取消请求,当服务被要求停止时,Host的StopAsync等待超时后抛出异常。
  • 解决:将stoppingToken传入GetSystemStatus(),在方法内部的IO操作、循环中加入stoppingToken.ThrowIfCancellationRequested()或检查IsCancellationRequested状态,及时响应取消指令:
await systemStatusProcess.GetSystemStatus(stoppingToken);
  1. 日志配置适配问题
    服务环境中没有控制台窗口,添加Console日志提供器可能引发潜在错误,间接导致服务终止。
  • 解决:移除logging.AddConsole(),仅保留EventLog;或通过条件判断仅在非服务模式下添加Console日志:
if (!WindowsServiceHelpers.IsWindowsService())
{
    logging.AddConsole();
}
  1. 服务账户权限不足
    直接运行.exe使用当前用户权限,而Windows服务默认使用受限账户(如Local System),可能导致GetSystemStatus()中访问文件、数据库或系统资源的操作失败,引发服务终止。
  • 解决:检查服务运行账户的权限,赋予必要资源的访问权限;在GetSystemStatus()中添加详细日志,定位具体失败的操作环节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:55:37