[英]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.