在调用 Dispose 后释放对组件的所有引用

本文关键字:引用 组件 调用 Dispose 释放 | 更新日期: 2023-09-27 17:57:06

关于Component类MSDN的Dispose()方法,这里说-

The Dispose method leaves the Component in an unusable state. After calling Dispose, you must release all references to the Component so the garbage collector can reclaim the memory that the Component was occupying.

现在比方说,我有以下代码——

public partial class Form1 : Form
{
    private Form2 form2;
    public Form1()
    {
        InitializeComponent();
        form2 = new Form2();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        form2.Show();
        //do something with form2            
        form2.Dispose();
        ???  ???  ???
        //form2 = null;           
    }
}
假设 form2

包含一些非托管资源,我需要立即释放这些资源,当然我希望 form2 被正确垃圾回收。那么,在form2上调用Dispose()后,我应该如何release all references to the Component呢?我需要设置form2 = null;什么的吗?请指教。事先谢谢。

编辑:

@Ed·

你提到——

even if it were scoped to the method it would be free for garbage collection as soon as the method exits

您能否在以下情况下告诉对象form2到底发生了什么?

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        this.ShowForm2();
    }
    private void ShowForm2()
    {
        Form2 form2 = new Form2();
        form2.Show();
    }
}  

该方法ShowForm2退出,但form2对象绝对不是垃圾回收。它仍在显示。

在调用 Dispose 后释放对组件的所有引用

,是的,设置对null的唯一引用有效,但你的例子是人为的。 在编写良好的代码中,您只需要创建一个函数本地的Form2实例:

private void button1_Click(object sender, EventArgs e)
{
    using (var form2 = new Form2())
    {
        // do something with form2
    }
}

现在你没有什么可担心的,因为你使对象的范围尽可能窄。

您不希望对 Dispose d 对象的实时引用,因为它允许您在释放它们后使用它们。我写了相当多的 C#,并且从未为此目的显式将变量设置为 null。 您可以以更确定的方式管理对象生存期。

编辑:

根据您的编辑和问题:

方法 ShowForm2 退出,但 form2 对象绝对没有被垃圾回收。它仍在显示。

是的,在这种情况下,表单在关闭之前无法进行GC'd(并且您也无法调用Dispose()。这是因为表单的 GC"根"仍然存在,尽管它在代码中不可见。

正确的语句是,当应用程序不再使用对象时,该对象符合 GC 的条件。可以在此处找到更深入的内容。