2013-10-08 3 views
0

개발자는 일부 항목을 수동으로 해제하지 않으면 WinForms ToolStrip 컨트롤 사용으로 인해 관리되는 메모리 누수가 발생할 수 있음을 알고 있습니다. 시스템의 내부 이벤트 핸들러 Microsoft.Win32.SystemEvents.UserPreferenceChanged 이벤트를 의미합니다. 리소스를 제대로 해제하려면 설명 된대로 ToolStrip Dispose 메서드를 명시 적으로 호출해야합니다 (예 : this 또는 this 게시물).ToolStrip.Dispose()가 System.ComponentModel.Component의 메모리 누수를 피하는 데 도움이되지 않습니다.

그러나이 경우 System.ComponentModel.Component의 자손에서 ToolStrip을 사용하면 도움이되지 않습니다. 적어도 내 경우에는 그렇습니다.

Private Class DropDownFilterBox 
    Inherits System.ComponentModel.Component 

    Private WithEvents fToolStripMain As New AutoFilterToolStrip 
    Private WithEvents fToolStripOKCancel As New AutoFilterToolStrip 
    Private WithEvents fContextMenuStripCustomFilterOperators As New ContextMenuStrip 
    Private WithEvents fToolStripDropDownCustomFilterDatePicker As New ToolStripDropDown 
    Private WithEvents fToolStripControlHostCustomFilterDatePicker As New AutoFilterToolStripControlHostDatePicker 

    ....................... 

    Public Overloads Sub Dispose() 
     fToolStripMain.Dispose() 
     fToolStripOKCancel.Dispose() 
     fContextMenuStripCustomFilterOperators.Dispose() 
     fToolStripDropDownCustomFilterDatePicker.Dispose() 
     fToolStripControlHostCustomFilterDatePicker.Dispose() 
     MyBase.Dispose() 
    End Sub 

End Class 

AutoFilterToolStrip는 다음과 같이 정의된다 : 여기에 코드의 해당 부분

Private Class AutoFilterToolStrip 
    Inherits ToolStrip 
    ...................... 
End Class 

는, 그러나 이것은 우리의 상황에서 문제가되지해야한다.

필요하면 사용 된 리소스를 정리하기 위해 DropDownFilterBox.Dispose를 수동으로 호출하기도하지만 아무런 효과가없는 것 같습니다.

일부 개발자는이 경우 ToolStrip에서 UserPreferenceChanged 이벤트 처리기를 자동으로 제거해야하므로 ToolStrips (Visible 속성을 False로 설정)을 숨기는 것이 좋습니다. 예, 작업을 수행해야하는 내부 HookStaticEvents 메서드가 호출됩니다. 그러나 이것은 또한 도움이되지 않습니다.

RemoveHandler Microsoft.Win32.SystemEvents.UserPreferenceChanged, _ 
    DirectCast(_ 
    System.Delegate.CreateDelegate(GetType(Microsoft.Win32.UserPreferenceChangedEventHandler), fToolStripMain, "OnUserPreferenceChanged"), _ 
     Microsoft.Win32.UserPreferenceChangedEventHandler _ 
    ) 

을하지만,이 또한 영향을주지 않습니다

난 반사를 사용하여 수동으로 문제 이벤트 핸들러를 분리했습니다.

우리의 경우이 메모리 누수 문제를 극복하는 방법과 ToolStrip.Dispose의 명시 적 호출이 우리의 경우에 작동하지 않는 이유에 대한 아이디어가 있습니까?

우리는 .NET Framework 4+ (클라이언트 프로파일) 용 VB.NET 2010에서 개발합니다.

답변

1

내 코드의 누락 된 부분은 다음이었다

Dim myOverflowButton As ToolStripOverflow 
myOverflowButton = DirectCast(fToolStripMain.OverflowButton.DropDown, ToolStripOverflow) 
If (myOverflowButton IsNot Nothing) Then 
    myOverflowButton.Dispose() 
End If 
myOverflowButton = DirectCast(fToolStripOKCancel.OverflowButton.DropDown, ToolStripOverflow) 
If (myOverflowButton IsNot Nothing) Then 
    myOverflowButton.Dispose() 
End If 

ToolStrip에 자동으로 소위 오버 플로우 버튼을 생성, 또한 메모리 누수가 발생할 수 UserPreferenceChanged 이벤트를 구독! 이에 대한 자세한 정보는 여기 (ToolStrip memory leak)에서 확인할 수 있습니다.

지금 내 구성 요소의 폐기 방법의 전체 목록은 다음과 같습니다

Public Overloads Sub Dispose() 
    With fContainer.Controls 
     .Remove(fToolStripMain) 
     .Remove(fToolStripOKCancel) 
    End With 

    fToolStripMain.Visible = False 
    fToolStripOKCancel.Visible = False 
    fContextMenuStripCustomFilterOperators.Visible = False 
    fToolStripDropDownCustomFilterDatePicker.Visible = False 
    fToolStripControlHostCustomFilterDatePicker.Visible = False 

    fToolStripMain.Dispose() 
    fToolStripOKCancel.Dispose() 
    fContextMenuStripCustomFilterOperators.Dispose() 
    fToolStripDropDownCustomFilterDatePicker.Dispose() 
    fToolStripControlHostCustomFilterDatePicker.Dispose() 

    Dim myOverflowButton As ToolStripOverflow 
    myOverflowButton = DirectCast(fToolStripMain.OverflowButton.DropDown, ToolStripOverflow) 
    If (myOverflowButton IsNot Nothing) Then 
     myOverflowButton.Dispose() 
    End If 
    myOverflowButton = DirectCast(fToolStripOKCancel.OverflowButton.DropDown, ToolStripOverflow) 
    If (myOverflowButton IsNot Nothing) Then 
     myOverflowButton.Dispose() 
    End If 

    ' Dispose calls for other used components 

    MyBase.Dispose() 
End Sub 

나는 또한 CodeProject의 기사 Memory Leak Detection in .NET에 설명 된 관리 코드에서 메모리 누수를 찾는 기술은 나에게 많은 도움 것을 인정해야한다 해결책을 찾는데 - BTW, 상업적 메모리 프로파일 러를 사는데 아무런 돈도 쓰지 않는다.