使用AutomationElement类时可能存在内存泄漏问题。

3
我正在编写一个程序,将我的浏览历史记录在文本文件中。它从Chrome窗口中获取URL并将其写入文本文件。它将Chrome窗口句柄作为参数,并将URL写入输出参数。代码如下:

我正在编写一个程序,将我的浏览历史记录在文本文件中。它从Chrome窗口中获取URL并将其写入文本文件。它将Chrome窗口句柄作为参数,并将URL写入输出参数。代码如下:

static AutomationElement elm;// = AutomationElement.FromHandle(handle);
static AutomationElement elmUrlBar;  
public static void GetChromeUrl(IntPtr handle, out string url)
    {
        string namedProperty = "Address and search bar" ;
        url = null;
        elm = AutomationElement.FromHandle(handle);
        elmUrlBar = elm.FindFirst(TreeScope.Descendants,
          new PropertyCondition(AutomationElement.NameProperty, namedProperty));
        if (elmUrlBar != null)
        {
            AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns();
            if (patterns.Length > 0)
            {
                ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0]);
                url = val.Current.Value;
            }
        }
    }

我使用计时器回调每5秒钟调用这个方法,它从Chrome浏览器窗口返回正确的URL。因此,它能够正常工作,尽管似乎没有释放AutomationElement对象所占用的内存,导致该应用程序使用的RAM不断增长。 我使用dotMemory 4.0和ants memory profiler 8对其进行了分析,发现AutomationElement对象被创建,但垃圾收集器未将其删除。有人知道如何解决这个问题吗?


如果您重构代码并将AutomationElement对象包装在using(){}语句中,会发生什么?你也可以实现IDisposable吗?你还可以调用GC.Collect()吗? - MethodMan
1个回答

1
我目前工作的公司也遇到了这个问题。这篇文章中提供了解决方案UIAutomation Memory Issue。基本上,您需要一种从您正在自动化的应用程序中调用GC的方法,因为自动化元素将添加到大对象堆中并需要3~分钟才能在此时处理它们,如果没有指针指向它们。

遇到了类似的问题。如果可能的话,你能分享一下你的解决方案代码吗? - Awais Umar
很遗憾,我之前测试的方法并不可行。自己调用GC.Collect()并不是一个好主意,而且你需要能够暴露一些方法来从测试应用程序与被测应用程序之间进行通信以触发它。所有这些都会带来很多问题。在遇到更多无法解决的内存泄漏后,我们最终在测试应用程序中构建了监视AUT内存消耗并在达到某个内存限制时重新启动它的功能。 - Max Young
@AwaisUmar 我们后来遇到的具体错误是,根据此论坛帖子 https://www.infragistics.com/community/forums/f/ultimate-ui-for-wpf/77267/dockmanager---memoryleak#data-id=436587 ,WPF本身正在泄漏AutomationElements。这个问题不仅限于infragistics,它与使用ItemsControlAutomationPeer的任何控件有关。如果您寻找Brian Lagunas 6年前的帖子,您将看到我所指的问题。 - Max Young
@AwaisUmar 你可以在这个文件中看到Brian所指的错误 https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Automation/Peers/ItemsControlAutomationPeer.cs,200172deda1fceba ,并且它至今仍然存在。本质上,他们使用弱引用,但是将项目作为弱引用的键使用强引用,因此它永远不会被清除。例如,这将发生在像TreeViews和ListViews这样的控件中,但我确信这不仅适用于这些控件。 - Max Young
@AwaisUmar 如果你对此有疑问,我会将所有内容移动到问题中以获得更好的格式,但我认为在这里引用所有这些内容是不合适的。 - Max Young
谢谢你回复我,Max。实际上,我正在使用你在第一条评论中提到的特定内存限制方法。我认为让GC自己完成工作会更好。我有一个与这个问题相关的问题打开。 https://stackoverflow.com/questions/61876201/automation-in-windows-form-application-eating-a-lot-of-ram - Awais Umar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接