在 .NET 中 Task.Delay() 的参考源中,我遇到了代码片段:
// ... and create our timer and make sure that it stays rooted.
if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout
{
promise.Timer = new Timer(state => ((DelayPromise)state).Complete(), promise, millisecondsDelay, Timeout.Infinite);
promise.Timer.KeepRootedWhileScheduled();
}
方法
KeepRootedWhileScheduled
是这样实现的:
GC.SuppressFinalize(m_timer);
打电话GC.SuppressFinalize
的目的是什么? 它是否真的为垃圾收集器建立了对象的根,注释是否不正确,或者还有其他我误解的内容吗?
非常重要的,当你不这样做时它就会停止滴答作响。 但不,这个方法有一个非常容易让人误解的名字。 它可能在早期版本中做了一些非常不同的事情,然后后来发现它所做的任何做作都是不必要的。 不应该,任务保留了对它的引用。 当然,这是在无法访问早期源代码的情况下的推测。
剩下的就是微优化,在 .NET Framework 代码中没有什么异常。 据推测,无论发生什么,计时器总是会被释放,因此不需要它的终结器。 听起来不错,您必须考虑任务在执行 Delay() 时遇到异常的场景。 嗯,那不会发生。 顺便说一句,编辑相当草率,这在框架代码中并不常见。