我有一个简单的WPF程序,只有一个按钮,没有事件处理逻辑。然后,我使用UIAutomation框架连续多次单击该按钮。最后,我看了一下WPF程序使用的内存,它似乎在增长。
有谁知道为什么会这样,我怎样才能防止这种情况发生?
下面是简单的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程序并用鼠标单击按钮时,这些对象不会出现。
更新:
我尝试使用Visual的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
发布于 2013-09-26 22:41:41
在与微软客户支持部门交谈后,我们找到了问题的答案。在内部,WPF给自己三分钟时间来响应UI自动化事件。要做到这一点,它从一个计时器开始。看来,即使事件被立即响应,计时器直到三分钟结束后才会消失。
因此,解决问题的方法是等待计时器过期,然后执行GC.Collect。那么内存问题就会消失。这不是一个很好的解决办法,但它适用于我们的情况。
发布于 2013-09-16 16:00:47
尝试在for循环之外声明buttonElement和invokePattern等对象。
https://stackoverflow.com/questions/18832122
复制相似问题