Я работаю над проектом, который использует элемент управления WPF WebBrowser (System.Windows.Controls.WebBrowser). Элемент веб-браузера программы является одним из многих видов деятельности, которые пользователь может задействовать и открывается в отдельном окне. После того, как пользователь переходит от браузера, окно закрывается, и каждое окно создается каждый раз, когда пользователь возвращается в браузер. Мы заметили значительную утечку памяти/снижение производительности в нашей программе (использование до ~ 700 мб от ~ 200 начальных) при постоянном использовании браузера. Не сумев найти какие-либо точки утечки ресурсов в нашем собственном коде, я решил определить, была ли проблема с нашим собственным элементом управления WebBrowser или элементом управления WPF.
Я создал новый простой проект, состоящий только из MainWindow и WebWindow. Кнопка в главном окне запускает браузер, направленный на gmail (сайт, на который мы обратили внимание, самая большая проблема с немногими, которые мы рассмотрели). После закрытия этого окна освобождение ресурсов (без уменьшения размера виртуальной машины в диспетчере задач или Process Explorer), а количество объектов GDI, обработчиков которых обрабатывается процессом, не уменьшается (программа запускается с ~ 30, открывая браузер он до ~ 140 и после закрытия браузера ~ 140 все еще открыт). Открытие другого браузера вызывает больше ручек и выделяет больше ресурсов. Кроме того, эта проблема не устраняется путем специального вызова Dispose() в элементе управления WebBrowser. Код прост и выглядит следующим образом:
Главное окно:
<Window x:Class="WebBrowserMemory.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Button Click="Button_Click">Gmail</Button>
</StackPanel>
</Grid>
</Window>
Button_Click:
private void Button_Click(object sender, RoutedEventArgs e)
{
var win = new WebWindow();
win.Show();
win.Browser.Navigate("http://www.gmail.com");
}
Веб-окно:
<Window x:Class="WebBrowserMemory.WebWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WebWindow" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<WebBrowser Grid.Row="0" x:Name="_browser" />
<Button Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10" Padding="10" Click="Button_Click">Close</Button>
</Grid>
</Window>
Соответствующий код:
public WebBrowser Browser {
get { return _browser; }
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Close();
}
protected override void OnClosed(EventArgs e)
{
_browser.Dispose();
base.OnClosed(e);
}
Кто-нибудь еще столкнулся с этой проблемой с помощью элемента управления WPF WebBrowser?
[UPDATE: обновленное сообщение для указания вызова Dispose() в соответствии с ответом itowlson - даже вызов Dispose() в элементе управления веб-браузером не освобождает ресурсы]