完全形成处置和释放记忆

问题描述 投票:0回答:1

我已经阅读了大量关于“类处理”的主题,我确实理解了如何做到这一点并且工作正常!同时“形式处置”不一样,资源还在泄漏!

我在做什么:

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

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

在这种情况下,通过“结束使用”形式以“Dispose”方法终止。

例如:

我有一个有一个类的表单(它包含参数和其他类)。在初始化表单事件中,表单(本身)占用12Mb的内存(我在进程资源管理器中测量它)加上我的类占用10Mb(Disposable并在Dispose事件上的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的内存。

我做错了什么?

vb.net winforms resources dispose
1个回答
0
投票

我对VB并不是很熟悉,但我认为它会做类似于使用winforms for C#完成它们的方式

确保在处理表单时处理A Form的所有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();
     }
}

如果需要,您可以添加事件处理程序以通知其他人正在处理对象

© www.soinside.com 2019 - 2024. All rights reserved.