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

关于.NET Core中System.Threading.Timer在Linux服务仅触发一次的问题咨询

System.Threading.Timer在Linux下仅触发一次的问题

我之前也碰到过完全一样的情况!当时排查了好久才揪出根源,核心是.NET跨平台下的GC行为差异搞的鬼。

问题本质

System.Threading.Timer的实例如果没有被强引用持续持有,在Linux的GC策略下会被快速回收——因为它内部依赖弱引用机制来管理生命周期。而Windows环境里,要么调试器会自动阻止GC回收这类对象,要么默认GC策略更宽松,所以定时器能正常周期性触发。

举个典型的错误写法,很容易踩这个坑:

// 错误示例:局部变量的Timer,方法执行完就会失去引用
void StartTimer()
{
    var timer = new System.Threading.Timer(Callback, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
}

这种代码在Windows调试时可能一切正常,但发布到Linux后,方法执行完毕局部变量timer就没了引用,GC一回收定时器就停了,自然只会触发一次。

可行的解决办法

除了你已经改用的System.Timers.Timer(它内部会自动持有自身的强引用),还可以给System.Threading.Timer手动加个强引用:

// 正确示例:把Timer存在类字段里,保持持续引用
private System.Threading.Timer _timer;

void StartTimer()
{
    _timer = new System.Threading.Timer(Callback, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
}

只要类实例还存活,_timer就不会被GC回收,定时器就能正常周期性触发。

当时的排查小技巧

我当时还通过这些方式验证了问题:

  • 在回调方法里打印GC.GetTotalMemory(false),观察GC触发时机和定时器停止的关联
  • 使用dotnet dump工具分析内存,确认Timer实例是否真的被回收

不少同行都遇到过这个坑,主要是忽略了System.Threading.Timer的引用特性,再加上跨平台GC行为的差异,才导致了这种“Windows正常、Linux异常”的诡异情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:16:51