合法使用GC.Collect?

时间:2015-09-22 12:08:37

标签: c# .net garbage-collection

请考虑使用System.Threading.Timer类的此代码。

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? 如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

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

正如你在圆周方式中发现的那样,问题在于,仅仅因为重新分配对象并不意味着“旧的”不会继续射击。这与在这种情况下对象的附加事件处理程序(可以使僵尸对象保持活动)或排队的线程池回调有关。 Dispose不能保证你不会再获得另一个回调,因为回调是由线程池排队的,并且在下次调用回调之前不会清除。

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

答案 1 :(得分:0)

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