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

C#中Timers.Timer的stateinfo参数垃圾回收问题咨询

关于C# Timers.Timer中state对象的GC回收问题

问题1:stateinfo(即new ei.StringID)是否会被C#自动回收?

会的。ei.StringID属于.NET托管对象,只要满足垃圾回收器(GC)的回收条件——没有任何存活的引用指向它,就会被GC自动回收。

问题2:它会在何时被回收?

回收时机完全取决于对象的引用持有情况,分以下几种场景:

  • Timer回调执行完成后:如果回调执行结束后,没有其他代码再引用这个stateinfo对象,GC会在下次执行垃圾回收操作时将其回收。
  • Timer未触发就被丢弃:如果MyEventNotification多次被调用,每次都会创建新的Timer并覆盖m_Timer,旧的Timer如果没有被手动调用Dispose(),它会一直持有旧的stateinfo引用,直到旧Timer本身被GC回收(此时旧的stateinfo也会失去引用,随之被回收)。
  • Timer被手动释放:如果主动调用m_Timer.Dispose(),Timer会释放对stateinfo的引用,之后只要没有其他引用指向该对象,GC就会将其回收。

额外代码优化提示

你的代码里有两个需要注意的细节:

  1. 每次创建新Timer前,应该先释放旧的Timer,避免内存泄漏:
public void MyEventNotification(in MyEventInfo ei)
{
  if (ei.State!=MyEventState.Completed) {
    // 先释放旧Timer资源
    m_Timer?.Dispose();
    m_Timer=new Timer(TimerHandler, ei.StringID, 1000, Timeout.Infinite);
  }
}
  1. 回调里的类型转换要确保ei.StringID确实是string类型,否则会抛出强制转换异常,建议做安全检查:
public void TimerHandler(Object stateinfo) {
  if(stateinfo is string id) {
    // 安全使用id做后续操作
    if (m_JustForShow==1) {
      // 这里的代码运行在线程池线程中,并非创建Timer的线程,但只要当前类实例还存活,就可以访问成员变量(注意线程安全问题)
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:56:05