Я работаю над проектом, в котором используется элемент управления 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?
[ОБНОВЛЕНИЕ: обновленное сообщение для указания вызова Dispose () согласно ответу itowlson - даже вызов Dispose () в элементе управления веб-браузера не освобождает ресурсы]