2013-09-16 39 views
8

我有,只是有没有事件处理逻辑的一个按钮一个简单的WPF程序。然后我使用UIAutomation框架连续多次单击该按钮。最后,我看看WPF程序使用的内存,它似乎在增长和增长。UIAutomation内存问题

谁知道为什么是这样的话,我怎么能防止这种情况发生?

下面是简单的WPF程序(没有后面的代码中):

<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测试程序:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string appPath = @"..\..\..\SimpleApplication\bin\Debug\SimpleApplication.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(); 
    } 
} 

下面是我的机器上的程序的结果:

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内存分析器查看它,出现的新对象WPF应用程序来自System.Threading命名空间。当我运行本身的WPF程序,并用鼠标点击按钮这些对象都没有出现。

UPDATE:

我试图做使用Visual Studio的CodedUI类似的测试,和相同的8个对象出现在那种情况下泄漏也是如此。出现泄漏的对象包括:

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[] 

我也提交了一个bug微软:

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

回答

4

谈论微软客户支持后,我们找到了解决问题的办法。在内部,WPF给自己三分钟来响应UI自动化事件。要做到这一点,它启动一个计时器。看来,即使该事件立即作出回应,定时器不会消失,直到后三分钟结束了。

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

0

试图声明的对象,如buttonElement,和invokePattern外的for循环。

+0

这似乎放慢内存增长,但无法阻止它。现在它结束于53 MB而不是60 MB。 – user2784456