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

C#中IHostedService定时器无法重复触发LoadData方法问题

.NET Core 5 Timer仅首次执行的问题修复方案

问题根源

  • Timer被垃圾回收:StartAsync方法中声明的_timer是局部变量,方法执行完毕后没有被类实例持有引用,会被GC回收,导致后续定时触发失效。
  • async void的隐患:LoadData使用async void修饰,异步操作抛出的异常无法被正常捕获,一旦出现异常会直接终止Timer的后续触发;同时Timer无法等待异步回调完成,可能引发并发问题。

修复代码

1. 将Timer改为类字段,避免被GC回收

private System.Threading.Timer _timer;

public Task StartAsync(CancellationToken stoppingToken)
{
    // 注册应用停止时的Timer清理逻辑
    stoppingToken.Register(() => _timer?.Change(Timeout.Infinite, 0));

    _timer = new System.Threading.Timer(LoadData, null, TimeSpan.Zero, TimeSpan.FromMinutes(2));

    return Task.CompletedTask;
}

2. 替换async void为async Task并处理异常

// Timer回调用同步方法包装异步逻辑
private void LoadData(object state)
{
    // 用_忽略返回值,避免编译器警告,同时确保异常被内部处理
    _ = LoadDataAsync(state);
}

// 实际异步业务逻辑,用async Task保证异常可捕获
private async Task LoadDataAsync(object state)
{
    try
    {
        var res = await _repository.GetAsync();
        // ... 其他业务逻辑
    }
    catch (Exception ex)
    {
        // 这里添加异常处理,比如写入日志,避免异常终止Timer
    }
}

关键说明

  • 类字段_timer持有强引用,确保GC不会回收Timer实例,保证定时触发持续有效。
  • 通过stoppingToken注册清理逻辑,在应用停止时将Timer改为无限期等待,避免资源泄漏。
  • 用async Task替代async void,配合异常捕获,防止异步异常导致Timer停止运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:42:06