GC.SuppressFinalize 是否使对象保持根目录

Does GC.SuppressFinalize keep an object rooted

在 .NET 中 Task.Delay() 的参考源中,我遇到了 a snippet of code:

// ... 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();
}

方法KeepRootedWhileScheduledimplemented thusly:

GC.SuppressFinalize(m_timer);

调用GC.SuppressFinalize的目的是什么?它是否真的为垃圾收集器生成了对象的根,注释是否不正确,或者是否还有其他我误解的地方?

保持 System.Threading.Timer root 肯定 非常 重要,如果不这样做,它就会停止运行。但是不,这个方法有一个非常误导的名字。它可能在早期版本中做了一些非常不同的事情,后来发现它所做的任何 hokey-pokey 都是不必要的。它不应该,任务保留对它的引用。当然,这是在没有访问早期源代码的情况下的推测。

剩下的是微优化,在 .NET Framework 代码中没有什么异常。据推测,无论发生什么情况,计时器总是会被处理掉,因此不需要它的终结器。听起来不错,您必须考虑任务在执行 Delay() 时遇到异常的场景。好吧,那不会发生。顺便说一句,编辑相当草率,这在框架代码中并不常见。