2013-09-16 37 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