我有一个通过构造函数安装计时器的类。
public class ScanInput
{
private Timer m_Timer;
:
public ScanInput(bool bAuto)
{
Auto = bAuto;
if (bAuto)
{
m_Timer = new Timer();
m_Timer.Interval = 1000 * DEFAULTTIMERSECONDS;
m_Timer.Enabled = true;
m_Timer.Tick += new EventHandler(OnTimerTick);
}
else
m_Timer = null;
}
:
protected void OnTimerTick(object sender, EventArgs e)
{
:
}
}
当此对象超出正在运行的计时器的范围时会发生什么?我是否必须实现一个IDisposable接口才能优先停止计时器并清理它?
答案 0 :(得分:0)
如果您的类有IDisposable
个字段,那么它本身应该实现IDisposable
以允许您的类的用户释放非托管资源(在您的情况下是底层OS计时器资源)。
Microsoft解释了Dispose Pattern:
DO 在包含一次性类型实例的类型上实现Basic Dispose Pattern。有关基本模式的详细信息,请参阅基本处理模式部分。
如果你没有在课堂上实施IDisposable
,就会发生两件事:
计时器使用的非托管资源在不再使用时不会被清除。相反,这会在计时器实例被定时器具有终结器时被垃圾收集后发生。
定时器非托管资源通过最终确定来清理,需要终结器线程的额外工作,这是最好的避免。
虽然你当然应该尝试编写最佳代码,但这些点中的任何一点都不会对小应用程序造成太大影响。
在您的案例中,实施IDisposable
非常简单:
sealed class ScanInput : IDisposable
{
public void Dispose()
{
m_Timer.Dispose();
}
}
可以处置已经放置的物品,这样就不会保护m_Timer.Dispose()
的呼叫。但是,如果已经处置ObjectDisposedException
并且该方法不再能够执行其工作,您可能希望在其他一些方法中抛出ScanInput
。
该类是密封的,以避免实现IDisposable
和允许派生成员覆盖所处理的内容的复杂性。
为了使这个有用,你当然必须在完成使用它之后处理ScanInput
实例。否则,定时器非托管资源的清理只会在您控制之外发生。
答案 1 :(得分:0)
我是否必须实现IDisposable接口才能优雅地停止 计时器首先清理它?
使用Dispose()
实例后,应该调用Timer
方法。是的,你可以在你的类上实现IDisposable
并实现Dispose()
方法,在你的类型的dispose实现中你应该调用timer dispose