何时在c#中删除计时器事件处理程序?

3

我是一名能帮助翻译的助手。

我有一个WindowsForm应用程序——“弹跳球”,因此我在表单上有一个计时器,因为在每个计时器滴答声中我都会移动球。

在我的表单c'tor中,我有以下代码:

public Form1(){

  timer = new Timer();
  timerHandler = new EventHandler(timerTick);
  timer.Tick += timerHandler;
  timer.Enabled = true;
}

现在,当用户关闭这个应用程序时,我需要删除“EventHandler”吗?我有一个退出按钮,所以当用户单击它时,我会显示一个弹出对话框询问他是否真的要退出应用程序。如果他点击“是”,我会关闭应用程序,否则什么也不会发生。
因此,在我的退出按钮代码中,我编写了以下代码:
DialogResult result= MessageBox.Show("Do you really want to quit?", "Exit",  
                                     MessageBoxButtons.YesNo);
        if (result == DialogResult.Yes)
        {
             timer.Tick -= timerHandler;
             this.close();
        }

我需要担心timerHandler还是GC在应用程序关闭时销毁了它?

1
当用户点击应用程序时,所有对象都将被销毁(除了后台线程),无需担心。 - Arsen Mkrtchyan
1个回答

8
现在当用户关闭这个应用程序时,我是否需要删除“EventHandler”?
不需要。除此之外,如果整个应用程序停止,那么这意味着进程无论如何都会死掉,因此这没关系。
但是,即使没有这种情况,计时器也将在窗体同时合适地进行垃圾回收 - 因此,在这种情况下,事件处理程序不会使对象比需要更长时间存活。 (当然,这假设您的“timer”变量是实例变量。)
编辑:上面只涉及垃圾回收方面。进一步思考后,这可能存在潜在的问题(我不确定实现细节):如果定时器在窗体关闭并隐含丢弃之后但事件循环仍在运行时触发,那么您可能会得到一个试图在已释放的窗体上移动球的计时器触发失败。
解决这个问题的最佳方法不是删除tick处理程序(依我之见) - 而是在窗体被释放时处理定时器(即在Dispose方法中 - 可能通过将其添加到组件容器中,但我对此还不完全确定)。
这不是物品是否将进行垃圾回收的问题 - 而是事件处理程序是否在不再适当时调用它(因为窗体已被释放)。如果窗体关闭立即关闭事件循环,那就没问题 - 但我不确定。

谢谢您的回答,那么我可以从我的代码中删除代码行“timer.Tick -= timerHandler”吗? - Elior
@Elior:是的,在垃圾回收方面不需要它。进一步思考,我想知道这里是否存在竞争条件 - 我将在我的答案中编辑更多细节。 - Jon Skeet
@John Skeet,谢谢您 :) ,我会接受您的答案,只是我正在等待这个选项对我可用,因为我刚刚注册.. - Elior
所以你的意思是当用户想要关闭应用程序时,要处理计时器?但如果它是计时器的实例..(而且它确实是)垃圾回收应该自己处理,对吧? - Elior
@Elior:看我的编辑——垃圾收集器收集它,但如果计时器在它被垃圾收集之前触发会发生什么? - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接