C# 在不手动调用GC的情况下完成

C# 在不手动调用GC的情况下完成,c#,winforms,memory-leaks,garbage-collection,C#,Winforms,Memory Leaks,Garbage Collection,我们的C#应用程序中有一组特定的操作,这些操作会导致RAM继续增长,直到窗体关闭。此表单存在很长时间,一些用户不会整天关闭此表单 基本上,表单frmRelationalSearch调用表单frmCombinedSearch搜索一个人,表单frmCombinedSearch关闭时,表单frmCombinedSearch将该人返回表单frmRelationalSearch。表单frmRelationalSearch是这里长期存在的表单,而表单frmCombinedSearch似乎是导致问题的表单 出

我们的C#应用程序中有一组特定的操作,这些操作会导致RAM继续增长,直到窗体关闭。此表单存在很长时间,一些用户不会整天关闭此表单


基本上,表单
frmRelationalSearch
调用表单
frmCombinedSearch
搜索一个人,表单
frmCombinedSearch
关闭时,表单
frmCombinedSearch
将该人返回表单
frmRelationalSearch
。表单
frmRelationalSearch
是这里长期存在的表单,而表单
frmCombinedSearch
似乎是导致问题的表单

出于测试目的,我在每个人员搜索周期中手动添加了
GC.Collect()
GC.WaitForPendingFinalizers()
,以查看它是否确实是内存泄漏。我已经意识到表单
frmCombinedSearch
确实是由GC收集的,并且可能只是因为它在终结器队列中而存在很长时间。我不明白的是,在我们的代码wince中,如何在不手动调用
GC.Collect()
GC.WaitForPendingFinalizers()
的情况下解决RAM使用量不断增长的问题这是一个糟糕的做法

我已经用dotMemory和ANTS内存分析器确认了这一点

我该怎么处理?在这种情况下,可以手动调用GC吗

这是当前的代码:

private void btnSearch_Click(object sender, EventArgs e)
{
    // Without these three lines, the RAM will continue to grow until
    // this form (frmRelationalSearch) is closed.

    // GC.Collect();
    // GC.WaitForPendingFinalizers();
    // GC.Collect();

    frmCombinedSearch frm = new frmCombinedSearch();
    try
    {
        // Custom code which just shows the form in the current tab
        frm.ShowInTab(this.ParentTabPage);
    }
    catch (Exception ex)
    {
        this.ShowException(ex);
    }
}
在这两个分析器中,
frmCombinedSearch
由于终结器队列而被保留

编辑
ShowInTab()
是非阻塞的,因此我不能使用
using
语句来处理它,因为它将在创建后立即被处理。

WinForms需要关闭或处理()。我建议使用
使用

private void btnSearch_Click(object sender, EventArgs e)
{
    using (frmCombinedSearch frm = new frmCombinedSearch())
    {
        try
        {
            // Custom code which just shows the form in the current tab
            frm.ShowInTab(this.ParentTabPage);
        }
        catch (Exception ex)
        {
            this.ShowException(ex);
        }
    }
}

frmCombinedSearch
frmRelationalSearch
是一次性的吗?如果是,您可以实现使用,以便在关闭后收集

如下所示:

using(frmCombinedSearch frm = new frmCombinedSearch()){
    try {
       frm.ShowInTab(this.ParentTabPage); }
    catch(Exception ex) {
       this.ShowException(ex); } }

您正在处理
frmCombinedSearch
?您不能将
frmCombinedSearch
表单逻辑移动到用户控件中吗?因为您显然希望在TabControl中显示该表单(是吗?)。因此,您只需创建一次UC,就可以直接管理和处置其资源。顺便说一句,您没有显示如何/何时处理
frm
对象。
frmCombineSearch
在设计器文件的表单关闭事件中调用了
Dispose
。我不能使用
using
语句,因为如果我这样做,那么当表单在TabControl中仍然可见时,我将完全处理它。我只需要打开它,然后马上关闭它。是的,您可以,也不能在表单类中调用
dispose()
。类处理它初始化的资源,而不是它自己。您需要处理在调用者类(
frmRelationalSearch
)中创建的
frmRelationalSearch
)对象。
frmRelationalSearch
在关闭时被处理,因为它在
ShowInTab()
方法中以
form.Show()
显示。搜索完成后,它将关闭。