2017-05-08 9 views
0

私はvb.net winformsアプリケーションを持っています。サードパーティのコントロールによって引き起こされるメモリリークがあります。私は、メモリリークを解消する代わりに、削減するという選択肢が残っています。プログラムでwinフォームをユーザーコントロールに設定しないでください。

フォームには、Friend WithEventsとして宣言されたユーザーコントロールがいくつかあります。フォームがメモリ内にあり、ユーザーコントロールへの参照を保持しているため、フォームが閉じられたときにGCedされません。しかし、私がdisposeに何もないユーザーコントロール参照を設定すると、メモリリークが減少します。

これをアプリケーションの1つではなく、アプリケーション全体に展開したいと考えています。どのように私は、すべてのユーザーコントロールをスキャンし、処分に何も設定する反射を使用するだろうか?面白いことに、ユーザーコントロールは "Friend WithEvents"という署名を使って宣言されています。スキャン中に何とかこれを使用することは可能ですか?

+1

リフレクションは必要ありません。自分で作成したコントロールの「Dispose」は必要ありません。他のものが実際のUserControlである場合、子コントロールの処理は組み込まれています(動的コントロールを行っている場合を除きます)。 – Plutonix

答えて

1

@Plutonixは、コントロールを破棄すると、その子コントロールを無効にして破棄します。ダイナミックコントロールを使用していると思われる場合は、コントロールを再帰的に処分できますか?

Sub DisposeControls(parentControl as Control) 
    For each control as Control in parentControl.Controls 
     If control.HasChildren() Then Call Me.DisposeControls(control) 
     control.Dispose() 
    Next 
End Sub 

編集:上記のコードがコンパイルされるかどうかはわかりませんが、擬似コードとして扱います。

+0

コードは実線ですが、メモリの問題には役立ちません。それはまだメモリの削減を与えるdoes notはユーザーコントロールrefsをnullに設定すると –

+1

を与えるそれは本当に面白いです!サードパーティのコントロールライブラリがdisposeの基本機能をオーバーライドし、この[MSDN](https://msdn.microsoft.com/en-us/library/system.idisposable)に従ってCloseHandleを実装していない可能性があります(v = vs.110).aspx#Anchor_3)の記事を参照してください。答えをソリューションとして追加していただきありがとうございます。結果をどのように達成したかを確認してください! – DeeKayy90

1

私はこれをやってしまった。その最適ではないが、それは本当にうまくいく。私はすべてのフォームに基本フォームを継承しています。その形式の配置されたメソッドでは、このリフレクションコードを使用します。

Private Sub BaseForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed 
    NullifyReferencesOnDispose() 
    RemoveHandler Me.Disposed, AddressOf BaseForm_Disposed 
End Sub 

Protected Overridable Sub NullifyReferencesOnDispose() 
    Dim typ = CType(Me.GetType, Reflection.TypeInfo) 
    For Each fld In typ.DeclaredFields 
     fld.SetValue(Me, Nothing) 
    Next 
End Sub 
関連する問題