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

无引用的System.Threading.Timer为何不会被垃圾回收?

关于System.Threading.Timer垃圾回收行为的解答

你观测到的现象和旧资料不符的核心原因是不同.NET运行时版本对Timer的实现逻辑存在差异,以下是针对你的三个问题的具体说明:

  • 为什么定时器会持续触发?
    你的测试运行在.NET Core 2.1+/ .NET 5+版本下,该场景下Timer实例不会被GC回收,底层调度逻辑会持续生效,因此绑定的回调函数会被反复调用。

  • 该定时器是否被GC回收?原因是什么?
    没有被GC回收,原因和运行时版本直接相关:

    在.NET Framework版本中,System.Threading.Timer的实现逻辑和旧资料描述一致:激活状态的Timer只会被全局Timer队列持有弱引用,当没有其他强引用指向Timer实例时,弱引用不会阻止GC回收实例,回收后定时器就会停止触发。
    而在.NET Core 2.1及之后的所有.NET版本(包括.NET 5/6/7/8等),官方修改了Timer的实现:所有处于激活状态(已调用Change启动且未调用Dispose释放)的Timer实例,都会被全局Timer队列持有强引用,直到实例被显式释放为止,因此不会被GC回收,定时器会持续运行。

  • 持有定时器引用的主体是哪个?
    持有强引用的是.NET运行时内部的全局TimerQueue单例对象,该对象负责管理所有Timer的调度逻辑,新版本实现中添加强引用的目的是避免用户误操作丢失Timer引用后定时器意外停止的问题。

你可以通过将测试项目的目标框架修改为.NET Framework 4.x复现旧资料描述的行为,定时器运行一段时间后就会被GC回收,回调次数远低于预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:54:00