完全形成并释放内存

时间:2019-02-16 20:05:29

标签: vb.net winforms resources dispose

我已经阅读了很多有关“课堂布置”的主题,并且我确实知道如何做到这一点,并且效果很好!同时,“表单处理”并不相同,资源仍在泄漏!

我在做什么:

通过“使用”方法初始化表格:

Using f as New Form
    f.ShowDialog()
    'my code
End using

在这种情况下,以“终止使用”形式以“处置”方法终止。

例如:

我有一个带有类的表单(它包含参数和其他类)。 在初始化表单事件时,表单(自身)占用12Mb的内存(我在进程资源管理器中对其进行测量),而我的类则占用10Mb(在Dispose事件中,Disposable也在Dispose表单之前进行处置)。处置完表格后(再次对其进行度量),我看到班级已处置,并且(班级)资源完全免费,表格未释放资源。换句话说,我杀死了10Mb(级别),但不要杀死12Mb(形式)。

我的处置代码:

Private Sub Form_Disposed(sender As Object, e As EventArgs) Handles 
Me.Disposed
    If Not fDisposed Then
        MyPersonalClass.Dispose()'class
        MyPersonalClass = Nothing
        fDisposed = True
        GC.SuppressFinalize(Me)
        GC.Collect()
        Finalize()
    End If
End Sub

这很糟糕。如果大多数时候我使用这些表单,并且在处置后它们仍然没有释放资源,则每个打开的表单在关闭后将在内存中保留大约10-12Mb。如果我打开表单100次,它将冻结超过1Gb的内存。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我对VB并不是很熟悉,但是我认为它会做与使用Winforms for C#来完成类似的事情

最简单的方法是在处理表单时确保A Form的所有Disposable对象均被处理,以保留Disposable对象的集合。您可以为此使用现有的类Sytem.ComponentModel.Component。缺点是它仅接受实现interface IComponent的对象。如果只有几个必须处理的类还没有此接口,则这是最简单的方法。否则,请设计自己的DisposableCollection

class DisposableCollection : List<object>, IDisposable
{
     public bool IsDisposed {get, private set} = false;

     private IEnumerable<IDisposable> DisposableItems => this.OfType<IDisposable>();

     public void Dispose()
     {
         if (!this.IsDisposed)
         {
               // Dispose all disposable items
               foreach (IDisposable disposableItem in this.DisposableItems)
               {
                   disposableItem.Dispose();
               }
               this.disposed = true;
         }  
     }
}

用法:

class MyForm : Form
{
     private readonly DisposableCollection disposables = new DisposableCollection();

     public MyForm()
     {
          // create and add all your items to disposables
     }

     protected override void OnDisposing(bool disposing)
     {
           this.disposables.Dispose();
     }
}

如果需要,您可以添加事件处理程序以通知其他人该对象已被处置