GC.Collect 的合法使用?

legitimate use of GC.Collect?

考虑使用 System.Threading.Timer class.

的代码
mTimer = new System.Threading.Timer(someTimer, null, dueTime.TotalMilliseconds, Timeout.Infinite);

现在我有一个列表,其中包含定时器函数必须每天执行的时间,然后它将定时器重置为下一次它应该执行的时间。

private static void someTimer(object state)
{
  TimeSpan dueTime = GetDueTime();
  mTimer = new System.Threading.Timer(someTimer, null,      (int)dueTime.TotalMilliseconds, System.Threading.Timeout.Infinite);
}

但是我注意到定时器函数在一段时间后执行了多次,这似乎与垃圾收集器有关。旧对象仍将触发事件直到它被垃圾收集。

所以一个简单的 GC.Collect(0) 修复了它,定时器函数只执行一次。 我知道普遍的看法是永远不必手动调用垃圾收集器,所以我的问题是这是否是 GC.Collect 的合法使用? 还应该如何解决这个问题?

当您不再希望计时器触发事件​​时,您应该 Dispose() 计时器。

System.Threading.Timer 有一个 Change 方法,允许您修改计时器而不是重新创建一个新计时器。

正如您以迂回方式发现的那样,问题在于,仅仅因为您重新分配了对象并不意味着 "old" 对象不会继续发射。在这种情况下,这与对象的附加事件处理程序(可以使僵尸对象保持活动状态)或排队的线程池回调有关。 Dispose 不保证您不会再收到回调,因为回调已在线程池中排队,并且在下次调用回调之前不会被清除。

推荐的方法是使用更改功能。