这是为什么.NET UIAutomation程序漏水/池?这是、程序、NET、UIAutomation

2023-09-03 06:37:35 作者:此情可待追忆

我有使用.net UIAutomation一个应用程序,它最终运行内存不足和崩溃只是监视窗口正在显示和关闭。似乎更容易在VB比C#表明这一点,但发生在相同的两种方式。这似乎是一个泄漏/池在底层的代理对象。大部分内存不被示出为在使用中作为达网络存储器

这是如何得到这个停止泄漏,并继续监测StructureChangedEvents任何想法?

 进口System.Windows.Automation
公共类Form1中

委派子AddListCallback(BYVAL文本作为字符串)
昏暗UIAeventHandler作为StructureChangedEventHandler

私人小组Form1_Load的(BYVAL发件人为System.Object的,BYVALË作为System.EventArgs)把手MyBase.Load
    BtnStartStop.Text =停止
    订阅()
结束小组

私人小组BtnStartStop_Click(BYVAL发件人为System.Object的,BYVALË作为System.EventArgs)把手BtnStartStop.Click
    如果开始= BtnStartStop.Text然后
        BtnStartStop.Text =停止
        订阅()
    其他
        BtnStartStop.Text =开始
        退订()
        lbEvents.Items.Clear()
        GC.GetTotalMemory(真)
    结束如果
结束小组

公用Sub订阅()
    UIAeventHandler =新StructureChangedEventHandler(AddressOf OnUIAutomationEvent)
    Automation.AddStructureChangedEventHandler(AutomationElement.RootElement,TreeScope.Descendants,UIAeventHandler)
结束小组

公用Sub退订()
    Automation.RemoveStructureChangedEventHandler(AutomationElement.RootElement,UIAeventHandler)
结束小组

'''<总结>
'''AutomationEventHandler委托。
'''< /总结>
'''< PARAM NAME =SRC>引发事件的对象< /参数>
'''< PARAM NAME =E>事件参数和LT; /参数>
私人小组OnUIAutomationEvent(SRC BYVAL作为对象,BYVAL E上StructureChangedEventArgs)
    确保元素仍然存在。元素如提示即可消失
    '前的事件被处理。
    如果e.StructureChangeType = StructureChangeType.ChildrenInvalidated然后
        退出小组
    结束如果
    昏暗sourceElement作为的AutomationElement
    尝试
        sourceElement = DirectCast(SRC,的AutomationElement)
    抓住EX作为ElementNotAvailableException
        退出小组
    结束尝试
    TODO处理已订阅的其他事件。
    Console.WriteLine(元素:&放大器; sourceElement.Current.LocalizedControlType和放大器;&放大器; sourceElement.Current.Name _
       &放大器; 结构体变更类型:&放大器; [枚举] .GetName(的GetType(StructureChangeType),e.StructureChangeType)_
       &放大器; 运行时ID:&放大器;的getString(e.GetRuntimeId()))
结束小组

专用功能的getString(BYVAL整数作为整数())作为字符串
    的getString =
    对于每一个我作为整数整数
        的getString =的getString和放大器; 与& i.ToString
    下一个
端功能
末级
 

解决方案

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

  Automation.RemoveAllEventHandlers();
UIAeventHandler = NULL;
 
IOS UIAutomation xcode 6

UIAutomation会保留一些线程活着,只要你有一个AutomationEventHandler对象周围。它的pretty的多一个黑盒子给我,但是上面已经定了,我把所有的问题。

I've got an app using .net UIAutomation, it eventually runs out of memory and crashes just monitoring windows being shown and closed. Seemed easier to show this in VB than C# but happens the same either way. It appears to be a leak/pool in the underlying proxy objects. Most of the memory is not being shown as in use as .net memory.

Any ideas on how to get this to stop leaking and still monitor 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

解决方案

I would do something like this when you unsubscribe:

Automation.RemoveAllEventHandlers();
UIAeventHandler = null;

UIAutomation will keep some threads alive as long as you've got an AutomationEventHandler object around. Its pretty much a black box to me, but the above has fixed all issues that I had.