我有使用.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;
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.