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
不保证您不会再收到回调,因为回调已在线程池中排队,并且在下次调用回调之前不会被清除。
推荐的方法是使用更改功能。
考虑使用 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
不保证您不会再收到回调,因为回调已在线程池中排队,并且在下次调用回调之前不会被清除。
推荐的方法是使用更改功能。