使用对话框表单周围的语句来确保垃圾回收

时间:2011-11-29 17:32:48

标签: c# winforms garbage-collection using-statement resource-leak

我们有一个包含数千种表单的Windows窗体应用程序。

其中许多通过ShowDialog()方法暂时显示为对话框。

此应用程序已存在多年,我们发现由于表单中的各种资源泄漏或其使用的控件,许多表单未及时收集垃圾。

具体来说,我们已经找到了未正确处理的GDI +资源的示例,尽管可能还有其他类型的资源泄漏尚未被表征。

虽然解决这个问题的正确方法显然是要经历每一种形式和每一种控制,并消除所有的资源问题。这需要一些时间才能完成。

作为一个短期替代方案,我们发现在表单上显式调用Dispose()似乎启动了垃圾收集过程,并且表单及其资源被立即释放。

我的问题是,在一个using语句中包装每个表单的ShowDialog()块是否是一个合理的解决方法,以便在显示表单后调用Dispose(),这也是一个很好的做法。一般?

例如,更改现有代码:

public void ShowMyForm()
{
    MyForm myForm = new MyForm();
    myForm.ShowDialog();
}

对此:

public void ShowMyForm()
{
    using (MyForm myForm = new MyForm())
    {
        myForm.ShowDialog();
    }
}

在我们的测试中,第一个例子永远不会调用MyForm的Dispose()方法,但第二个例子会立即调用它。

当我们花时间追踪每个特定的资源问题时,这似乎是一种合理的方法作为短期解决方法吗?

我们是否可以考虑采用其他方法来确定和解决这些类型的资源问题的短期解决方法和/或方法?

3 个答案:

答案 0 :(得分:12)

根据MSDN,您必须在使用ShowDialog显示的表单上显式调用Dispose(与Show方法不同):

  

当表单显示为模式对话框时,单击“关闭”   按钮(表单右上角带有X的按钮)   导致隐藏窗体并设置DialogResult属性   到DialogResult.Cancel。与非模态形式不同,Close方法是   当用户单击关闭表单时,.NET Framework不会调用   对话框的按钮或设置DialogResult属性的值。   相反,表单是隐藏的,可以再次显示而不创建   对话框的新实例。因为表单显示为对话框   框是隐藏而不是关闭,你必须调用Dispose方法   当您的申请不再需要表格时的表格。

答案 1 :(得分:2)

对于模态对话框,您应该使用模式:

using ( var dlg = new MyDialog() )
{
    // other code here to initialize, etc.
    dlg.ShowDialog();
}

由于 MyDialog 源自表单,而Form实现 IDisposable ,因此此模式将正确清理对话框。

这不应该是“短期解决方法”,而是您应该调用所有模态对话框的标准方式。

无模式对话框是另一个故事。您需要自己跟踪它们,并在应用程序的适当位置调用 Dispose

答案 2 :(得分:1)

通常,对于实现IDisposable的对象,使用using语句是一种很好的方法。

一个小样本情况:

假设您有第三方“组件”。你不知道内部发生了什么 也许这个对象会创建一个临时文件并删除Dispose上的文件。如果你 不要拨打Dispose()并且不要使用using该文件永远不会被删除。

在您的情况下,只要您打开表单modal,就可以执行此操作。