动态系统.定时器.定时器和垃圾收集
本文关键字:定时器 系统 动态 | 更新日期: 2023-09-27 17:53:00
假设我动态地创建一个定时器:
System.Timers.Timer expirationTimer = new Timer(expiration * 60000);
expirationTimer.Elapsed += (sender, e) => removeExpiredCacheEntry(sessionID);
expirationTimer.Start();
当引用超出作用域时,Timer对象会被垃圾收集吗?如果是,事件还会触发吗?如果不是,那么在这种情况下如何避免内存泄漏?
谢谢!
根据这个答案,计时器对象确实符合垃圾收集的条件,并在某个点停止触发事件。
然而,垃圾收集被反过来阻止了。如果我们有
publisher.SomeEvent += target.SomeHandler;
那么"publisher"将使"target"保持存活,但"target"不会使"publisher"保持存活
一旦对象超出作用域,并且没有对它的额外引用。它最终会被垃圾收集起来。但这在一段时间内可能不会发生。因此,计时器可能会一直触发,直到它最终被垃圾收集。
这只是一个猜测,因为我目前没有能力测试它。
更新:我刚刚写了一个小的测试程序,看起来像这样:
static void Main(string[] args)
{
SetTimer();
Console.ReadLine();
}
private static void SetTimer()
{
Timer expirationTimer = new Timer(1000);
expirationTimer.Elapsed += (sender, e) => Notify(e);
expirationTimer.Start();
}
private static void Notify(ElapsedEventArgs e)
{
Console.WriteLine(string.Format("Notified! {0}", e.SignalTime));
}
计时器持续触发很长时间(我最终刚刚结束了程序)。有趣的是,我在main函数中插入了一个15秒的睡眠,然后调用GC.Collect()
,即使在强制垃圾收集之后计时器也会继续运行,尽管不能保证调用GC.Collect()
会实际做任何事情。
我还尝试在using语句中包装计时器,并且正确地立即禁用计时器(不向屏幕打印任何内容)。所以,我相信我的假设是正确的,垃圾收集将最终收集计时器,并处理它。但是没有办法确定这将是什么时候。