【问题标题】:Releasing all references to the Component after calling Dispose调用 Dispose 后释放对组件的所有引用
【发布时间】:2014-04-05 20:26:10
【问题描述】:

关于Component类MSDN hereDispose()方法说——

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 S.

你提到了——

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 对象肯定没有被垃圾回收。它仍在显示。

【问题讨论】:

    标签: c# .net winforms garbage-collection


    【解决方案1】:

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

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

    现在您无需担心任何事情,因为您将对象的范围保持在尽可能窄的范围内。

    您不希望对Disposed 对象进行实时引用,因为它使您可以在它们被释放后使用它们。我编写了相当多的 C#,并且从未为此目的明确地将变量设置为 null。您可以以更确定的方式管理对象的生命周期。

    编辑:

    根据您的编辑和问题:

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

    是的,在这种情况下,表单在关闭之前无法进行 GC(而且您也无法在其上调用 Dispose()。)这是因为表单仍然存在 GC“根”它在您的代码中不可见。

    正确的说法是当一个对象不再被应用程序使用时,它就有资格进行 GC。可以找到更深入的了解here

    【讨论】:

    • 嗯...这很有意义,使用 using 块。但是using 块仅确保当您离开该块时 form2 的 Dispose() 将被调用,仅此而已。我的问题是关于第二部分,你如何发布这个对 form2 的引用?我的事件手方法可能不止于此。
    • 对不起,我明白了,form2 对象的范围在 using 块内,而不是在整个 EventHandler 方法内。我的错。感谢您的帮助。
    • @NerotheZero:是的,确切地说,即使它的范围是方法,只要方法退出它就可以免费进行垃圾收集。很高兴能提供帮助。
    • 请参阅EDIT 部分。我添加了一个进一步的查询。谢谢。
    • @NerotheZero:添加了一些信息。顺便说一句,当有人回答您的问题时,我们鼓励您将答案标记为已接受。
    猜你喜欢
    • 1970-01-01
    • 2019-11-14
    • 2019-09-14
    • 2010-10-27
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多