UIAutomation 内存问题 [英] UIAutomation Memory Issue

查看:29
本文介绍了UIAutomation 内存问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 WPF 程序,它只有一个按钮,没有事件处理逻辑.然后我使用 UIAutomation 框架连续多次单击该按钮.最后看一下WPF程序使用的内存,好像还在增长.

I have a simple WPF program that just has a single button with no event handling logic. I then use the UIAutomation framework to click that button many times in a row. Finally, I look at the memory used by the WPF program and it seems to grow and grow.

有谁知道为什么会这样以及我如何防止这种情况发生?

Anyone know why this is the case and how I can prevent this from happening?

这是一个简单的 WPF 程序(后面的代码中没有任何内容):

Here is the simple WPF program (nothing in the code behind):

<Window x:Class="SimpleApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Simple Application"
        AutomationProperties.AutomationId="Simple Application"
        Height="350" Width="525">
    <Grid>
        <Button AutomationProperties.AutomationId="button" Height="50" Width="100">Click Me</Button>
    </Grid>
</Window>

这是 UIAutomation 测试程序:

Here is the UIAutomation test program:

class Program
{
    static void Main(string[] args)
    {
        string appPath = @"......SimpleApplicationinDebugSimpleApplication.exe";
        string winAutoId = "Simple Application";
        string buttonAutoId = "button";

        using (Process process = Process.Start(new ProcessStartInfo(appPath)))
        {
            Thread.Sleep(TimeSpan.FromSeconds(1));

            AutomationElement winElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, winAutoId));

            for (int i = 0; i < 1001; i++)
            {
                AutomationElement buttonElement = winElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, buttonAutoId));

                InvokePattern invokePattern = (InvokePattern)buttonElement.GetCurrentPattern(InvokePattern.Pattern);
                invokePattern.Invoke();

                process.Refresh();
                long totalMemory = process.WorkingSet64 + process.PagedMemorySize64;

                if (i % 100 == 0)
                {
                    Console.WriteLine("Memory = {0} MB", ((double)totalMemory) / (1024 * 1024));
                }
            }

            WindowPattern windowPattern = (WindowPattern)winElement.GetCurrentPattern(WindowPattern.Pattern);
            windowPattern.Close();
        }

        Console.WriteLine();
        Console.WriteLine("Press Enter to Continue...");
        Console.ReadLine();
    }
}

这是我机器上程序的结果:

Here are the results from the program on my machine:

Memory = 38.20703125 MB
Memory = 42.9296875 MB
Memory = 45.00390625 MB
Memory = 47.04296875 MB
Memory = 51.9296875 MB
Memory = 52.2890625 MB
Memory = 52.41015625 MB
Memory = 55.70703125 MB
Memory = 55.70703125 MB
Memory = 57.21484375 MB
Memory = 59.09375 MB

使用 .NET Memory Profiler 查看它,WPF 应用程序中出现的新对象来自 System.Threading 命名空间.当我自己运行 WPF 程序并用鼠标单击按钮时,这些对象不会出现.

Looking at it with the .NET Memory Profiler, the new objects that are appearing in the WPF application are from the System.Threading namespace. When I run the WPF program by itself and click the button with the mouse these objects do no appear.

更新:

我尝试使用 Visual Studio 的 CodedUI 进行类似的测试,在这种情况下,同样的 8 个对象似乎也发生了泄漏.出现泄漏的对象是:

I tried doing a similar test using Visual Studio's CodedUI, and the same 8 objects appeared to leak in that situation as well. The objects that appear to leak are:

System.Threading.CancellationTokenSource
System.Threading.TimerQueueTimer
System.Threading.SparselyPopulatedArray<CancellationCallbackInfo>[]
System.Threading.Timer
System.Threading.TimerHolder
System.Threading.SparselyPopulatedArray<CancellationCallbackInfo>
System.Threading.SparselyPopulatedArrayFragment<CancellationCallbackInfo>
System.Threading.CancellationCallbackInfo[]

我也向微软提交了一个错误:

I have also submitted a bug to Microsoft:

http://connect.microsoft.com/VisualStudio/feedback/details/801209/uiautomation-memory-issue

推荐答案

在与 Microsoft 客户支持交谈后,我们找到了问题的答案.在内部,WPF 给自己三分钟时间来响应 UI 自动化事件.为此,它启动一个计时器.看起来,即使立即响应事件,计时器也不会在三分钟结束后消失.

After talking to Microsoft customer support, we found the answer to the problem. Internally, WPF gives itself three minutes to respond to a UI Automation event. To do this, it starts off a timer. It appears that even if the event is responded to immediately, the timer does not go away until after the three minutes are up.

因此,该问题的解决方法是等到计时器到期,然后执行 GC.Collect.那么内存问题就会消失.不是一个很好的修复,但它适用于我们的情况.

So, the workaround to the problem is to wait until the timer expires and then do a GC.Collect. Then the memory issue will go away. Not a great fix, but it works for our situation.

这篇关于UIAutomation 内存问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆