forms时未配置定时器

我试图理解为什么在创建它的form时不会处理Windows.Forms.Timer 。 我有这个简单的forms:

 public partial class Form1 : Form { private System.Windows.Forms.Timer timer; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { timer = new Timer(); timer.Interval = 1000; timer.Tick += new EventHandler(OnTimer); timer.Enabled = true; } private void OnTimer(Object source, EventArgs e) { Debug.WriteLine("OnTimer entered"); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { this.Dispose(); } } 

当我关闭它时,会调用this.Dispose ,但会继续调用计时器触发事件​​。 我认为Dispose释放了被Dispose对象拥有的所有对象。 这是不真实的吗? Timer有特定的行为吗?

现在,我发现处理计时器的方法是做timer.Tick -= OnTimer; – 我在Form1_FormClosed事件中调用它。 这是一个好的解决方案,还是我应该这样做?

编辑

或者它是否更好:

 private void Form1_FormClosed(object sender, FormClosedEventArgs e) { timer.Dispose(); this.Dispose(); } 

正如我在之前的评论中告诉你的,你应该尝试:

 private Form1_FormClosing(...) { timer.Stop(); timer.Tick -= new EventHandler(OnTimer); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { timer.Dispose(); timer = null; } 

这很好,因为你阻止计时器再次循环(在FormClosing中)你可以检查其他部分(在这个例子中是非因为你正在关闭表单,但是作为例子)如果在使用它之前删除了该对象(计时器) 。
所以在其他部分你可以做到

 if (timer != null) // Note: this is false if you just use timer.Dispose() { .... } 

处理IDisposable类的一次性成员的唯一正确方法是在Dispose(bool disposing)方法中执行它(查看MSDN文章)。 换句话说,您可以打开自动生成的Form.Designer.cs文件并将其放在正确的方法中。

另一方面,如果通过VS Designer添加Timer (而不是自己实例化),它将被添加到components容器中:

 // autogenerated inside Form.Designer.cs, InitializeComponent() method this.timer = new System.Windows.Forms.Timer(this.components); 

然后在components构件处理时妥善处理:

 // autogenerated inside Form.Designer.cs, Dispose(bool disposing) method if (disposing && (components != null)) { components.Dispose(); } 

如果您想自己这样做,请记住,如果设计人员认为不需要,则设计器不会实例化components 。 因此,在您的情况下, components可能为null

解决此问题的最简单方法是:通过从工具箱中拖动来添加计时器,然后在Form_Load处理程序中启动它。

  private void Form1_FormClosed(object sender, FormClosedEventArgs e) { timer.Stop(); } 

我不应该把这个.Dispose(); 在表单关闭事件只是停止计时器。

EventHandler是持久引用,删除引用并在结束事件上或在不需要时立即停止计时器。 如果要检查定时器是否处理,请在已关闭事件中进行检查

简单的Timer.Dispose()删除计时器资源,包括将来停止计时器。

但是,在Dispose()返回之后,有可能是主动执行或坐在线程池的工作队列中等待执行的回调。

第二次重载,一旦定时器的所有回调都完成, Timer.Dispose(WaitHandle)将发出传入的对象信号。 这可以是任何WaitHandle ,例如ManualResetEvent

为了简化操作,您可以传入WaitHandle.InvalidHandle并且Timer.Dispose()仅在所有回调都已完成时返回。 这避免了必须分配一个真正的事件对象,通常是你想要做的。

由于WaitHandle是抽象的,你需要使用一点hack,即创建自己的子类。

 class InvalidWaitHandle : WaitHandle {} Timer tmr = new Timer(...); tmr.Dispose(new InvalidWaitHandle);