Pet*_*sky 9 .net c# garbage-collection timer
根据MSDN,应该保留对System.Threading.Timer的引用,否则它将被垃圾收集.因此,如果我运行此代码,它不会写任何消息(这是预期的行为):
static void Main(string[] args)
{
RunTimer();
GC.Collect();
Console.ReadKey();
}
public static void RunTimer()
{
new Timer(s => Console.WriteLine("Hello"), null, TimeSpan.FromSeconds(1), TimeSpan.Zero);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我通过将计时器存储在临时局部变量中来稍微修改代码,它会幸存并写入消息:
public static void RunTimer()
{
var timer = new Timer(s => Console.WriteLine("Hello"));
timer.Change(TimeSpan.FromSeconds(1), TimeSpan.Zero);
}
Run Code Online (Sandbox Code Playgroud)
在垃圾收集期间,显然无法从根或静态对象访问计时器.所以你能解释为什么计时器存活下来吗?保留的参考在哪里?
每个都Timer引用 a TimerHolder,后者引用 a TimerQueueTimer。TimerQueueTimer该实现通过调用 来保留对 的内部引用UpdateTimer()。
正常情况下,您的计时器可以自由收集、完成TimerHolderTimerQueueTimer并从内部队列中删除。但简单的构造函数以自身作为状态Timer(TimerCallback) 进行调用。TimerSetup()Timer因此,在这种特殊情况下, 的TimerQueueTimer状态会引用回Timer,从而阻止它被收集。
该效果与保留临时局部变量无关。由于该机制的内部结构,它恰好Timer起作用。按照 MSDN 的建议,保留对计时器的引用会更清晰、更安全。
| 归档时间: |
|
| 查看次数: |
529 次 |
| 最近记录: |