Nik*_*las 5 c# garbage-collection timer capture
可能重复:
定时器,事件和垃圾收集:我错过了什么?
private void TrayForm_Load(object sender, EventArgs e)
{
System.Timers.Timer HideMeTimer = new System.Timers.Timer(2500);
HideMeTimer.Elapsed +=
delegate(object sender2, System.Timers.ElapsedEventArgs e2)
{
this.Invoke(new Action(somestuff));
};
HideMeTimer.Start();
GC.Collect();
}
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我编译器将如何翻译吗?或者很好地解释为什么定时器在加载事件之后继续滴答作响.
(当最后一个引用消失时,不是规则,变量,GC有时会杀死对象!)
Bri*_*eon 13
你需要了解System.Timers.Timer幕后的情况.它是System.Threading.Timer课程的包装.当计时器启动时,它会创建一个新System.Threading.Timer实例并在实例中传递一个回调方法System.Timers.Timer.只要计时器保持启用状态,系统就会引用此回调委托.
我们还知道委托保留对包含目标方法的类的实例的引用.这就是为什么您的System.Timers.Timer实例没有被收集而且不会自动停止的原因.删除Elapsed事件处理程序不会解决此问题,因为该委托仅保存对TrayForm实例的引用.再一次,正是System.Threading.Timer这是保持对...的引用System.Timers.Timer.整个参考链仍然是根的,因为系统必须引用System.Threading.Timer它才能工作.
这是参考链:
System => _TimerCallback => Callback => System.Threading.Timer => Callback => System.Timers.Timer
Run Code Online (Sandbox Code Playgroud)
当您使用Reflector或ILSpy跟踪这一点时,您可以看到上面参考链中的"系统"通过TimerBase.AddTimerNative标记的方法发挥作用,MethodImplOptions.InternalCall因此我们无法确切地看到引用如何在此点之下生根.但是,它仍然根深蒂固.
如果您通过Enabled = false或禁用定时器Stop,它将处置底层System.Threading.Timer,而后者应该停止引用System.Timers.Timer.
| 归档时间: |
|
| 查看次数: |
1314 次 |
| 最近记录: |