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

System.Threading.Timer在服务器负载时无法周期性执行问题求助

问题根源分析

1. Async void 回调的隐患

你使用的System.Threading.Timer回调属于TimerCallback委托,要求返回void。而你传入的async (timerState) => await UpdateActivityAsync(_ipAddress)本质是async void方法,存在两个致命问题:

  • 异步操作抛出的异常会直接扩散到线程池,无法被常规try/catch捕获,一旦异常发生,可能导致线程池线程终止,进而中断Timer的后续调度。
  • 服务器负载较高时,异步操作可能长时间处于等待状态,Timer会误判回调已执行完成并继续触发下一次回调,当线程池资源被占满后,后续回调任务无法被调度,最终导致Timer看似“停止工作”。

2. HttpClient 管理不当(对应日志中的HttpMessageHandler清理)

日志里的HttpMessageHandler清理记录,说明UpdateActivityAsync方法中大概率频繁创建HttpClient实例。每次创建HttpClient都会生成一个HttpMessageHandler,这些Handler不会被立即释放,堆积到一定数量后GC会触发清理周期,该过程会占用大量CPU和内存资源,进一步加剧服务器负载,抢占Timer调度所需的线程池资源。


修复方案

方案1:修正Timer的异步回调写法

避免异常扩散到线程池,在async void回调内部捕获所有异常:

_activityTimer = new Timer(async (timerState) =>
{
    try
    {
        await UpdateActivityAsync(_ipAddress);
    }
    catch (Exception ex)
    {
        // 记录异常日志,防止异常影响Timer调度
        Serilog.Log.Error(ex, "UpdateActivityAsync执行失败");
    }
}, null, new Random().Next(1, 15000), 15000);

方案2:正确管理HttpClient实例

不要在UpdateActivityAsync中频繁创建HttpClient,改用以下两种方式复用实例:

  • 单例模式(非ASP.NET Core项目):
// 在类中定义静态HttpClient实例,全局复用
private static readonly HttpClient _httpClient = new HttpClient();

private async Task UpdateActivityAsync(string ipAddress)
{
    var response = await _httpClient.GetAsync($"http://{ipAddress}/activity");
    // 后续业务逻辑
}
  • IHttpClientFactory(ASP.NET Core项目):
    先在Program.cs中注册服务:
builder.Services.AddHttpClient();

再注入使用:

private readonly IHttpClientFactory _httpClientFactory;

// 构造函数注入
public YourService(IHttpClientFactory httpClientFactory)
{
    _httpClientFactory = httpClientFactory;
}

private async Task UpdateActivityAsync(string ipAddress)
{
    var httpClient = _httpClientFactory.CreateClient();
    var response = await httpClient.GetAsync($"http://{ipAddress}/activity");
    // 后续业务逻辑
}

这种方式能避免HttpMessageHandler堆积,减少GC清理频率,降低服务器负载。

方案3:确保Timer的生命周期正确

如果Timer所在的类是短暂生命周期对象(比如请求作用域服务),类被GC回收时Timer会自动停止。需确保Timer所在类是单例或长期存在的实例,或手动保持对Timer的引用,防止被GC回收。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:55:17