【发布时间】:2011-09-24 10:02:28
【问题描述】:
当我使用Dispose() 而不是Close() 关闭使用Show() 打开的表单时会发生什么?谁能详细告诉我,Dispose() 方法中发生了什么?
【问题讨论】:
-
C# 没有表单。请指定 WinForms/WPF/...
-
@Henk Holterman -我已经更新了我的问题
标签: winforms
当我使用Dispose() 而不是Close() 关闭使用Show() 打开的表单时会发生什么?谁能详细告诉我,Dispose() 方法中发生了什么?
【问题讨论】:
标签: winforms
Close() 和Dispose() 的基本区别在于,当调用Close() 方法时,任何托管资源都可以暂时关闭并可以再次打开。这意味着,对于同一个对象,可以重新打开或使用资源。 Dispose() 方法从内存中永久删除任何资源((未)托管)以进行清理,并且该资源不再存在以进行任何进一步的处理。
或者只是一般性陈述。调用Close() 的连接对象会将连接释放回池中。调用Dispose()会调用Close(),然后将连接字符串设置为null。
某些对象(例如 Stream)实现 IDisposable,但 Dispose 方法仅在您先将对象转换为 IDisposable 时才可用。它确实公开了一个Close() 方法。
我总是争辩说,当您完成对象时,您应该在任何实现 IDisposable 的对象上调用 Dispose()。即使它什么都不做。无论如何,jit 编译器都会从最终代码中对其进行优化。如果对象包含Close() 但不包含Dispose(),则调用Close()。
你也可以在IDispoable对象上使用using语句
using(SqlConnection con = new SqlConnection())
{
//code...
}
当块退出时,这将在 SqlConnection 上调用Dispose()。
【讨论】:
反编译这两个方法(Dispose和Close)原来是后者执行了两次额外的检查然后调用Dispose,就像这样:
object[] objArray;
if (base.GetState(262144))
{
throw new InvalidOperationException(SR.GetString("ClosingWhileCreatingHandle", new object[] { "Close" }));
}
if (base.IsHandleCreated)
{
this.closeReason = CloseReason.UserClosing;
base.SendMessage(16, 0, 0);
return;
}
base.Dispose();
来自文档:
当一个表单被关闭时,在对象中创建的所有资源都被关闭并且表单被释放。 [...] 表单未在 Close 上处理的两种情况是: (1) 它是多文档界面 (MDI) 应用程序的一部分,并且表单不可见; (2) 您已经使用 ShowDialog 显示了表单。在这些情况下,您将需要手动调用 Dispose 以将表单的所有控件标记为垃圾回收。
希望对你有帮助。
【讨论】:
其实在这种情况下Close()和Dispose()是完全不同的:
Close 通过发送适当的 Windows 消息来关闭表单。您将能够使用Open()再次打开表单
Dispose 完全释放表单资源,您将无法再次重复使用表单实例。
【讨论】: