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

发布于 2024-12-18 18:12:20 字数 869 浏览 2 评论 0原文

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

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

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

具体来说,我们发现了未正确处理 GDI+ 资源的示例,尽管可能还存在其他类型的资源泄漏尚未表征。

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

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

我的问题是,将每个表单的 ShowDialog() 块包装在 using 语句中是否是一个合理的解决方法,以便在显示表单后调用 Dispose() ,并且这通常也是一个很好的实践吗?

例如,将现有代码从以下位置更改为:

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

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

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

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

我们是否可以考虑其他方法作为短期解决方法和/或方法来识别和解决这些类型的资源问题?

We have a Windows Forms application that contains thousands of forms.

Many of these are temporarily displayed as dialogs via the ShowDialog() method.

This application has been around for years and we've discovered that many of the forms are not getting garbage collected in a timely manner due to various resource leaks in the form or the controls that it uses.

Specifically, we've found examples of GDI+ resources that aren't being disposed of properly, although there may be other types of resource leaks that have not yet been characterized.

Although the right way to resolve this is obviously to go through every form and every control and eliminate all of the resource problems. This will take some time to accomplish.

As an short term alternative, we have found that explicitly calling Dispose() on the form seems to initiate the garbage collection process and the form and its resources are deallocated immediately.

My question is whether is would be a reasonable workaround to wrap each form's ShowDialog() block in a using statement so that Dispose() is called after the form has been displayed, and also would this be a good practice to institute in general?

For example, change the existing code from this:

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

To this:

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

In our testing, MyForm's Dispose() method never gets called for the first example, but it gets called immediately for the second example.

Does this seem like a reasonable approach as a short term workaround while we spend the time tracking down each of the specific resource issues?

Are there other approaches that we could consider for a short term workaround and/or methodologies for identifying and resolving these types of resource issues?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

惜醉颜 2024-12-25 18:12:20

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

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

According to MSDN, you must explicitly call Dispose on forms shown using ShowDialog (unlike with the Show method):

When a form is displayed as a modal dialog box, clicking the Close
button (the button with an X at the upper-right corner of the form)
causes the form to be hidden and the DialogResult property to be set
to DialogResult.Cancel. Unlike non-modal forms, the Close method is
not called by the .NET Framework when the user clicks the close form
button of a dialog box or sets the value of the DialogResult property.
Instead the form is hidden and can be shown again without creating a
new instance of the dialog box. Because a form displayed as a dialog
box is hidden instead of closed, you must call the Dispose method of
the form when the form is no longer needed by your application.

完美的未来在梦里 2024-12-25 18:12:20

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

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

由于 MyDialog 派生自 Form,并且 Form 实现了 IDisposable,因此该模式将正确清理您的对话框。

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

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

For modal dialogs, you should use the pattern:

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

Since MyDialog is derived from Form, and Form implements IDisposable, this pattern will correctly cleanup your dialog.

This should not be a "short term workaround", but the standard way you should invoke all your modal dialogs.

Modeless dialogs are another story. You would need to keep track of them yourself, and call Dispose at the appropriate points in your application.

谈场末日恋爱 2024-12-25 18:12:20

一般来说,对于实现 IDisposable 的对象使用 using 语句是一个好方法。

一个小示例情况:

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

在您的情况下,只要打开表单modal,您也可以这样做。

In general it is a good way to use the using statement for objects that implement IDisposable.

A little sample situation:

Lets say you have a third party "component". You cant know what goes on internally
and maybe this objects creates a temp file and delete the file on Dispose. If you
dont call Dispose() and dont use using the file will never get deleted.

In your case you can do it too as long as you open your form modal.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文