IIS部署REST服务中Singleton定时HostedService运行异常问题
IIS部署的定时后台服务问题解决
问题1:仅当有请求时服务才运行
这是IIS默认的应用池闲置回收机制导致的——默认20分钟无请求就会回收进程,后台服务跟着终止。按下面步骤改配置:
- 打开IIS管理器,找到你的应用对应的应用池
- 右键选「高级设置」
- 把「闲置超时(分钟)」改成0(彻底禁用闲置回收)
- 把「定期时间间隔(分钟)」也改成0(禁用定时回收)
- 把「启动模式」设为AlwaysRunning(让应用池启动后立刻运行,不用等首次请求)
问题2:每小时生成多条日志
核心原因是服务被多次实例化,或者应用池频繁重启导致多个Timer同时工作。解决办法:
- 确认服务注册正确:在
Program.cs里必须用AddHostedService注册,这个方法默认把IHostedService注册为单例,确保只有一个实例:
builder.Services.AddHostedService<TimedHostedService>();
- 避免重复创建Timer:在
StartAsync里加个判断,防止重复初始化Timer:
public Task StartAsync(CancellationToken stoppingToken) { if (_timer != null) { _logger.LogWarning("Timer already exists, skip initialization"); return Task.CompletedTask; } _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromHours(1)); _logger.LogInformation("Timed Hosted Service started"); return Task.CompletedTask; }
额外优化建议
- 别在Timer回调里直接做耗时操作(比如数据库检查),线程池线程被阻塞会影响其他请求。改成异步执行:
private void DoWork(object? state) { // 用后台任务跑异步逻辑,不阻塞Timer回调 _ = RunDatabaseCheckAsync(); } private async Task RunDatabaseCheckAsync() { var count = Interlocked.Increment(ref executionCount); try { _logger.LogInformation("Starting database check. Count: {Count}", count); // 这里写你的数据库检查代码 await YourDatabaseCheckMethodAsync(); _logger.LogInformation("Database check done. Count: {Count}", count); } catch (Exception ex) { _logger.LogError(ex, "Database check failed. Count: {Count}", count); } }
- 停止服务时要处理未完成的任务,避免中途中断数据库操作:
private CancellationTokenSource? _taskCts; public Task StartAsync(CancellationToken stoppingToken) { _taskCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken); // 原有Timer初始化代码 } private async Task RunDatabaseCheckAsync() { try { // 把取消令牌传给数据库操作,支持中途取消 await YourDatabaseCheckMethodAsync(_taskCts.Token); } catch (OperationCanceledException) { _logger.LogInformation("Database check was canceled"); } } public async Task StopAsync(CancellationToken stoppingToken) { _timer?.Change(Timeout.Infinite, 0); _taskCts?.Cancel(); // 等待正在执行的任务收尾 await Task.Delay(1000); _logger.LogInformation("Timed Hosted Service stopped"); }
内容的提问来源于stack exchange,提问作者nick mackow
相关产品推荐
相关产品推荐

