2010-06-29 52 views
2

我有一个应用程序使用.net UIAutomation,它最终耗尽内存和崩溃只是监视窗口正在显示和关闭。似乎比C#更容易在VB中显示此内容,但发生的方式都是相同的。它似乎是底层代理对象中的泄漏/池。大多数内存不会被用作.net内存。这是为什么.net UIAutomation应用程序泄漏/共享?

任何想法如何让这个停止泄漏,并仍然监视StructureChangedEvents?

Imports System.Windows.Automation 
Public Class Form1 

Delegate Sub AddListCallback(ByVal Text As String) 
Dim UIAeventHandler As StructureChangedEventHandler 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    BtnStartStop.Text = "Stop" 
    Subscribe() 
End Sub 

Private Sub BtnStartStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnStartStop.Click 
    If "Start" = BtnStartStop.Text Then 
     BtnStartStop.Text = "Stop" 
     Subscribe() 
    Else 
     BtnStartStop.Text = "Start" 
     Unsubscribe() 
     lbEvents.Items.Clear() 
     GC.GetTotalMemory(True) 
    End If 
End Sub 

Public Sub Subscribe() 
    UIAeventHandler = New StructureChangedEventHandler(AddressOf OnUIAutomationEvent) 
    Automation.AddStructureChangedEventHandler(AutomationElement.RootElement, TreeScope.Descendants, UIAeventHandler) 
End Sub 

Public Sub Unsubscribe() 
    Automation.RemoveStructureChangedEventHandler(AutomationElement.RootElement, UIAeventHandler) 
End Sub 

''' <summary> 
''' AutomationEventHandler delegate. 
''' </summary> 
''' <param name="src">Object that raised the event.</param> 
''' <param name="e">Event arguments.</param> 
Private Sub OnUIAutomationEvent(ByVal src As Object, ByVal e As StructureChangedEventArgs) 
    ' Make sure the element still exists. Elements such as tooltips can disappear 
    ' before the event is processed. 
    If e.StructureChangeType = StructureChangeType.ChildrenInvalidated Then 
     Exit Sub 
    End If 
    Dim sourceElement As AutomationElement 
    Try 
     sourceElement = DirectCast(src, AutomationElement) 
    Catch ex As ElementNotAvailableException 
     Exit Sub 
    End Try 
    ' TODO Handle any other events that have been subscribed to. 
    Console.WriteLine("Element : """ & sourceElement.Current.LocalizedControlType & """ """ & sourceElement.Current.Name _ 
     & """ Struct Change Type : " & [Enum].GetName(GetType(StructureChangeType), e.StructureChangeType) _ 
     & " Runtime ID : " & getString(e.GetRuntimeId())) 
End Sub 

Private Function getString(ByVal ints As Integer()) As String 
    getString = "" 
    For Each i As Integer In ints 
     getString = getString & " " & i.ToString 
    Next 
End Function 
End Class 

回答

0

当你取消我会做这样的事情:

Automation.RemoveAllEventHandlers(); 
UIAeventHandler = null; 

UIAutomation会保留一些线程活着,只要你有围绕AutomationEventHandler对象。对我来说,它几乎是一个黑盒子,但上面已经解决了我所有的问题。

+0

嗯,我希望监听器在应用程序运行期间运行。我尝试了停止并开始多次,以查看它是否释放内存,包括清理处理程序的建议,以便可以通过GC进行清理。尽管不幸的是有些内存被释放,但每次添加事件处理程序后似乎仍会增加1000-2000k。 – 2010-06-30 16:22:26