System.ComponentModel.Component上的Dispose方法是否释放事件回调?

时间:2017-06-28 09:12:24

标签: c#

我在我的代码中使用了一个简单的Timer,并且我有一个回调,一旦时间到了就会被调用。

public TimerViewModel(int interval) {
    m_timer = new Timer(interval);
    m_timer.Elapsed += timer_Elapsed;
    // Other stuff.
}

然后我有一个dispose方法来处理我的类

public void Dispose() {
    m_timer.Dispose();
    // Dispose some more stuff.
}

现在我想知道在我处理定时器之前是否应该使用m_timer.Elapsed -= timer_Elapsed取消注册我的回调,或者这样做是否为定时器处理方法?

我已经阅读了MSDN网站关于Timers和关于Component的网站,但两者都只声明Dispose方法“释放组件使用的所有资源”,无论这意味着什么。

那么,Timer.Dispose()方法是否会释放我的回调?

1 个答案:

答案 0 :(得分:0)

我认为这是常见的做法,注册处理程序的实例也会注销它(我很确定Timer不会在其中取消注册处理程序的处理方法):

public void Dispose() {
    m_timer.Elapsed -= timer_Elapsed;
    m_timer.Dispose();
}

但是在TimerViewModel明显拥有m_timer引用的情况下,我不认为这很重要,因为计时器实例的生命周期将连接到您的{的生命周期{1}}实例。如果你错过了取消注册这个处理程序的重要性,那么两个实例都将被垃圾收集(一起)。

如果将timer-instance传入您的viewmodel或以某种方式公开,以便其他对象也可以保存它,则会出现问题。在这种情况下,当您的视图模型无法进行垃圾回收时,最终可能会出现内存泄漏,因为计时器无法进行垃圾回收,因为另一个对象具有对它的引用等。

但最重要的是要确保一方并取消注册您注册的所有处理程序。

但是,不要仅为此设置您的viewmodel IDisposable。只需确保只有vm-instance可以保存timer-instance-reference,然后你可以忽略取消注册并完全处理定时器。除非你创建了很多这些视图模型,并且确实需要始终保持较低的内存占用率。无论如何,当删除对viewmodel的引用时,它将被垃圾收集和处理。 IDisposable主要用于需要确保组件在告诉它时立即清理资源时,例如在循环一组图像时,你真的需要在将另一个位图加载到内存之前释放一个位图。 / p>