形式时未配置定时器

Oti*_*iel 8 c# dispose timer winforms

我试图理解为什么Windows.Forms.Timerform创建它的时候没有处理掉.我有这个简单的形式:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我关闭它时,会this.Dispose被调用,但会继续调用计时器触发事件​​.我以为它Dispose释放了被处置物体拥有的所有物体.这是不真实的吗?是否Timer有一个具体的行为吗?

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

编辑

或者只是做得更好:

private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
    timer.Dispose();
    this.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*rco 12

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

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

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

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


Gro*_*roo 5

处置IDisposable类的一次性成员的唯一正确方法是在其Dispose(bool disposing)方法内部进行检查(请参阅MSDN文章)。换句话说,您可以打开自动生成的Form.Designer.cs文件并将其放入适当的方法中。

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

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

然后在处置components成员时正确处置:

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

如果您想自己执行此操作,请记住,components如果设计师认为不需要,则不会实例化。因此,components可能是null您的情况。

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