处理后,ShowDialog中的内存泄漏

时间:2013-08-08 07:12:59

标签: c# winforms memory-leaks devpartner

我创建了一个示例窗体应用程序,它包含两种形式 - form1和form2。

Form1包含一个按钮,在单击时我将form2显示为对话框,如下所示。

private void button1_Click(object sender, EventArgs e)
        {
            Form2 form2 = new Form2();
            try
            {
                form2.ShowDialog();
            }
            catch (Exception ex)
            {

            }
            finally
            {
                if (form2 != null)
                {
                    form2.Dispose();
                    form2 = null;
                }
            }   

        }

然后我检查了应用程序,如单击按钮,然后它将打开form2,关闭它。并继续这6次。

当我使用 DevPartner 检查应用程序时,它始终显示为Form2 form2 = new Form2();已泄露

当我在网上查看时,它说如果我们使用ShowDialog,我们需要在关闭它之后处理该表单,即为什么我尝试在finally块中进行处理。但它仍然表明这条线正在泄漏。 任何人都可以就此漏洞提出建议。

3 个答案:

答案 0 :(得分:0)

您应该调查您的Form2,以查找对外部事件和根源引用的任何子选项。 所有这些都应该在表格处理时删除。

在以下代码中,泄漏的警告是对Idle事件的订阅。在Dispose方法中删除了订阅以避免泄漏。

Form2()
{
    Application.Idle += Application_Idle;
}

void Application_Idle(object sender, EventArgs e)
{   
}   

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        Application.Idle -= Application_Idle;
    }
}

答案 1 :(得分:0)

通常,当您使用 IDisposable 对象时,您应该在 using statement 中声明并实例化它。 using语句以正确的方式调用对象上的Dispose方法,并且一旦调用Dispose,它也会导致对象本身超出范围。在using块中,该对象是只读的,不能修改或重新分配。

using语句确保即使在对象上调用方法时发生异常,也会调用 Dispose

答案 2 :(得分:0)

这可能是您工具的检查规则,因为实例的创建不在try-catch中。

试试这样:

private void button1_Click(object sender, EventArgs e) {
    Form2 form2;
    try {
        form2 = new Form2();
        form2.ShowDialog();
    } finally {
        if (form2 != null) {
            form2.Dispose();
            form2 = null;
        }
    }
}

甚至更简单:

private void button1_Click(object sender, EventArgs e) {
    using (var form2 = new Form2()) {
        form2.ShowDialog();
    }
}