繁体   English   中英

什么时候物品被处理?

[英]When exactly does an item get disposed?

我的程序中有以下代码:

//Dialog Form Class

public int Age;

private void goButtonClick(object sender, EventArgs e)
{
     Age = trackBar1.Value;
     Close();
}

//Main Form Class

DialogForm df = new DialogForm();
df.ShowDialog();
df.Dispose();
if(df.Age >= 18)
{
    //do stuff
}

令人惊讶的是,我以为我需要一种方法来访问df.Age,因为它本来是由Close方法处理的,但令人惊讶的是,我可以访问这个值。 我假设这是垃圾收集器的某种智能,所以我在调用df.Age之前添加了df.Dispose() 只是为了看看会发生什么 ,但我仍然可以访问它。 所以我感到困惑? 为什么会这样? 什么时候物品被处理?

通常,答案是“当您的代码调用.Dispose() ”时,这通常意味着“当它离开using块时”,但是某些代码还有其他因素导致它被处理掉。 例如,在winform上,如果使用Show()方法显示它,则在窗体关闭时将其处理。

然而! 对于通过ShowDialog()显示的表单,这没有完成; 毕竟,它是模态的,所以预期寿命是显而易见的:

using(var df = new DialogForm())
{
    df.ShowDialog();
    if(df.Age >= 18)
    {
        //do stuff
    }
}

或更好:

int age;
using(var df = new DialogForm())
{
    df.ShowDialog();
    age = df.Age;
}
if(age >= 18)
{
    //do stuff
}

您可能还想检查ShowDialog()的返回值以查看它是否被取消等。

但要直接回答你的问题:问题中的表格从未妥善处理过。 永远不会调用IDisposable.Dispose()方法。

垃圾收集器会在某个时刻找到它,并将调用终结器 ,它将调用内置的Dispose(bool)模式,但这是winforms的实现细节,并没有正确处理。

另请参见MSDN for ShowDialog()

当窗体显示为模式对话框时,单击“关闭”按钮(窗体右上角带有X的按钮)将导致隐藏窗体并将DialogResult属性设置为DialogResult.Cancel。 与非模态窗体不同,当用户单击对话框的关闭窗体按钮或设置DialogResult属性的值时,.NET Framework不会调用Close方法。 而是隐藏表单,并且可以在不创建对话框的新实例的情况下再次显示该表单。 因为显示为对话框的窗体是隐藏而不是关闭的,所以当应用程序不再需要该窗体时,必须调用窗体的Dispose方法。

如果你能够调用df.Age ,这意味着你持有对象的引用(df只是一个引用)。 这反过来意味着垃圾收集器不会收集它,因此价值仍然存在。

并且Dispose()不会调用垃圾收集器,也不会删除引用。 Dispose用于您的对象需要显式释放某些资源的情况,并且您公开此方法以便可以调用它(而不是通过GC)。

这是因为您使用ShowDialog(..)调用。

在这种情况下,CLR不会调用表单上的Dispose ,以便您从表单中检索至少对话框结果。 所以这是你需要在收盘后明确调用Dispose(..)的唯一情况。

更多相关信息,您可以阅读社区内容Form.ShowDialog

垃圾收集器只会收集没有任何内容对该对象的引用的内存。 因此,在您的情况下,您仍然可以在主窗口中引用该对话框,直到引用该对话框的方法结束为止。

Dispose没有任何魔力。 这只是一个方法调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM