Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows窗体内存泄漏_C#_.net_Memory Leaks_Devexpress_Devexpress Windows Ui - Fatal编程技术网

C# Windows窗体内存泄漏

C# Windows窗体内存泄漏,c#,.net,memory-leaks,devexpress,devexpress-windows-ui,C#,.net,Memory Leaks,Devexpress,Devexpress Windows Ui,我在我的windows应用程序中看到一个轻微的内存泄漏。我在应用程序中使用DevExpress XtraForm。我看到的是表单的一个实例总是被保存在内存中。如果多次打开同一表单,它仍会保留上次打开表单的引用 例如,如果在应用程序中打开10个不同的窗体并关闭所有窗体,由于某些奇怪的“MdiClient对象引用LayoutEventArgs对象”,它仍然不会释放分配给它的内存。幸运的是,它保留了每种类型的单个项的引用 下面是指向Redgate内存探查器输出的链接 在上面的图表中,Departme

我在我的windows应用程序中看到一个轻微的内存泄漏。我在应用程序中使用DevExpress XtraForm。我看到的是表单的一个实例总是被保存在内存中。如果多次打开同一表单,它仍会保留上次打开表单的引用

例如,如果在应用程序中打开10个不同的窗体并关闭所有窗体,由于某些奇怪的“MdiClient对象引用LayoutEventArgs对象”,它仍然不会释放分配给它的内存。幸运的是,它保留了每种类型的单个项的引用

下面是指向Redgate内存探查器输出的链接

在上面的图表中,DepartmentsForm已禁用,但无法进行GCD,因为LayoutEventArgs的affectedComponent成员引用了它


如果您看到任何明显的错误,请给出建议。

根据我的经验,Windows窗体中存在一些情况,即释放的控件可以缓存在
LayoutEventArgs
对象中,并且看起来像WinForms中的某种小错误

一些细节:
System.Windows.Forms.Control
类型的每个实例都包含
LayoutEventArgs
type-
cachedLayoutEventArgs
的私有成员变量。而且,
LayoutEventArgs
通常包含对某些特定控件的引用。通过反射器,您可以清楚地看到所有这些事实。而且,有时,当子控件由于某些原因不影响父控件的布局过程时,
cachedLayoutEventArgs
字段不会被清除。您可以使用mdi父窗体模拟这种情况,方法是在关闭其子窗体时挂起mdi客户端的控件布局:

public partial class MdiParentForm : Form {
    public MdiParentForm () {
        InitializeComponent(); //  this.IsMdiContainer = true
    }
    void buttonAddMdiChild_Click(object sender, EventArgs e) {
        MdiChildForm f = new MdiChildForm();
        f.MdiParent = this;
        f.Show();
    }
    void buttonCloseMdiChild_Click(object sender, EventArgs e) {
        MdiClient client = GetMdiClient(this);
        client.SuspendLayout();

        if(ActiveMdiChild != null)
            ActiveMdiChild.Close();

        client.ResumeLayout(false); 
        // !!! At this point the MdiClient.cachedLayoutEventArgs contains the reference to disposed control (leak)
    }
    static MdiClient GetMdiClient(Form frm) {
        if(frm != null) {
            foreach(Control ctrl in frm.Controls) {
                if(ctrl is MdiClient)
                    return (MdiClient)ctrl;
            }
        }
        return null;
    }
}
class MdiChildForm : Form { }
有一个简单的解决方法-通过触发
PerformLayout
方法,可以有效地清除“缓存”实例:

class MdiChildForm : Form {
    MdiClient parent;
    protected override void OnParentChanged(EventArgs e) {
        base.OnParentChanged(e);
        var mdiClient = Parent as MdiClient;
        if(mdiClient != parent) {
            if(parent != null)
                parent.PerformLayout();
            parent = mdiClient;
        }
    }
}

另外,我建议您就此联系,以确保您描述的内存泄漏与他们的控件无关,并获得最终解决方案。

如果没有任何代码,就无法判断,即使这样,我怀疑可能很难提供帮助。我已随问题提供了对象保留图。