如果我有这样的方法:
public void Show()
{
Form1 f = new Form1();
f.ShowDialog();
}
即使它超出范围,我仍然需要在表单上调用 dispose ,这将有资格进行垃圾收集。
从一些测试来看,多次调用这个 Show() .. 在某些时候,GC 似乎收集了它,因为我可以看到内存激增,然后它在某个时间点下降。
从 MSDN 看来,当不再需要表单时,您必须调用 dispose 。
如果我有这样的方法:
public void Show()
{
Form1 f = new Form1();
f.ShowDialog();
}
即使它超出范围,我仍然需要在表单上调用 dispose ,这将有资格进行垃圾收集。
从一些测试来看,多次调用这个 Show() .. 在某些时候,GC 似乎收集了它,因为我可以看到内存激增,然后它在某个时间点下降。
从 MSDN 看来,当不再需要表单时,您必须调用 dispose 。
倾向于发生的情况是,如果项目具有纯托管资源,则不一定需要调用 dispose ,但强烈建议使用它,因为它使dispose 具有确定性。它并不总是需要(在技术意义上),因为这些托管资源现在很可能有资格进行 GC,或者默认情况下实际上没有什么可处理的,这是一个可扩展点。
对于非托管资源,Dispose Pattern建议实现一个终结器,它将在 GC 上调用。如果类型没有实现终结器并且没有调用 dispose,那么有可能(嗯,很可能)资源将未被处理。终结器是运行时提供的最后一次清理你的东西的机会——它们也是有时间限制的。
请注意,它不会使 GC 或托管内存回收具有确定性,处置不是 delete
来自 C++。处置的物品可能距离实际收集还有很长的路要走。但是,在托管世界中,您不关心确定性收集,只关心资源管理 - 换句话说,处置。
也就是说,如果类型是一次性的,我总是确保调用 Dispose 或使用using
语句,无论它使用托管资源还是非托管资源 - 这是预期的约定:
public void Show()
{
using (var f = new Form1())
{
f.ShowDialog();
} // Disposal, even on exceptions or nested return statements, occurs here.
}
更新:
在与 Servy 讨论之后,我觉得我必须将这一点表达为我建议尽可能处置的理由。在 的情况下MemoryStream
,它显然是一次性类型,但实际上目前不处理任何东西。
然而,依靠这一点,就是依靠. MemoryStream
如果将其更改为包含非托管资源,那么这将意味着依赖MemoryStream
没有任何东西可处置会成为问题。
在可能的情况下(与 情况一样IDisposable
)我更喜欢依赖公共合同。在这种情况下违反合同意味着我可以免受底层实现更改的影响。
尽管您很少需要在 C# imo 中手动处理,但您可以像这样尝试:
public void Show()
{
using (Form1 f = new Form1())
{
f.ShowDialog();
}
}
然后在使用部分的最后一个赞誉中,它将被自动处理掉。
你可以简单地做:
using (var f = new Form1())
f.ShowDialog();
ShowDialog 具有使 GDI 对象保持活动状态的副作用。为了避免 GDI 泄漏,我们需要适当地处理 ShowDialog。其中 Show 方法没有任何含义,GDI 会适当释放。建议处置 showDialog,不要依赖垃圾收集器。
如果要显式处置,请使用
using(Form1 f = new Form1()){
f.ShowDialog();
}
这确保了 Dispose() 被调用,以及它立即发生
在您的具体示例中,不,它不太可能特别有用。表单不会占用大量资源,因此如果清理它的某些部分代码需要更长的时间,它不会导致问题。如果该表单恰好持有用于播放视频的控件,那么它实际上可能持有大量资源,并且如果您确实在 dispose 方法中处理了这些资源,那么它是值得的花时间打电话给处置。但是,对于 99% 的表单,它们的 Dispose 方法将为空,无论您是否调用它都不太可能对您的程序产生任何(或任何明显的)影响。
它存在的原因主要是为了能够在重要的 1% 的情况下处理资源。
还值得注意的是,当 aForm
关闭时,它的Dispose
方法已经被调用。如果您想在表单关闭之前处理表单资源,则只需要添加using
或显式调用。Dispose
(这对我来说听起来通常是个坏主意)。这很容易测试。只需创建一个具有两种形式的项目。让第二种形式将事件处理程序附加到Disposing
事件并显示消息框或其他内容。然后,当您创建该表单的实例并将其显示(作为对话框或不作为对话框)时,您会看到当您关闭它时,消息框会立即弹出,即使您将“表单”实例保留在周围并且没有您曾经需要添加using
或Dispose
调用。
是的,您需要并且必须调用Dispose
或使用using
语句,否则可以,该实例保留在内存中。
如果您将 a 放入Timer
表单并在处理程序中设置断点,您可以检查它Timer.Tick
。即使在没有Dispose
处理程序的情况下关闭表单后也会被调用。