Утечка памяти при использовании WPF WebBrowser управляет в нескольких окнах

Я работаю над проектом, который использует управление WPF WebBrowser (Система. Windows. Средства управления. WebBrowser). Элемент веб-браузера программы является одной из многих операций, которые пользователь может вовлечь в и открыт в отдельном окне. После того, как пользователь перешел далеко от браузера, окно закрывается, и новое окно создается каждый раз, когда пользователь возвращается к браузеру. Мы замечали значительную утечку памяти / снижение производительности в нашей программе (использование, добирающееся ~700mb от ~200 начальных букв) после непрерывного использования браузера. После отказа найти любые точки утечек ресурсов в нашем собственном коде, я решил определить, была ли проблема с нашим собственным управлением оберткой WebBrowser или управлением WPF.

Я создал новый простой проект, состоящий только из MainWindow и WebWindow. Кнопка на главном окне запускает браузер, направленный на Gmail (сайт, с которым мы заметили самую большую проблему некоторых, мы исследовали). После закрытия этого окна нет никакого освобождения от ресурсов (никакое сокращение размера VM в Проводнике Диспетчера задач или Процесса), и количество GDI возражает, что процесс имеет дескрипторы к, не уменьшается (программа запускается с ~30, открытие браузера берет, это к ~140 и после закрытия браузера ~140 все еще открыто). Открытие другого браузера заставляет больше дескрипторов и больше ресурсов быть выделенным. Кроме того, эта проблема не решена специфическим вызовом, Располагают () на управлении 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?

[ОБНОВЛЕНИЕ: Обновленное сообщение для указания Располагает () вызов согласно ответу itowlson - даже вызов Располагает () на управлении веб-браузером, не освобождает ресурсы]

10
задан jeffora 15 January 2010 в 03:57
поделиться

2 ответа

Если у вас есть функция, которая принимает функцию в качестве параметра, и у вас нет кода, чтобы дать ему, вы можете пройти $. NOOP .

Я не могу думать о каких-либо таких случаях в jQuery, где параметр не является необязательным в первую очередь.

В отличие от написания функции () {} , прохождение $. NOOP не будет создавать новый экземпляр функции, сохраняя немного памяти. Однако, если все, что вы передаете его, чтобы изменять функциональный объект (например, funcparam.id = 2 ), прохождение $. NOOP будет беспокоиться.

-121--1102682-

В отличие от большинства элементов управления WPF, WebBrowser (поскольку он наследует от HWNDHOST), idisposable и инкапсулирует неуправляемые ресурсы. Окно WPF, в отличие от формы WinForms, не включена автоматически автоматически .

Добавьте включенный переопределений в ваше окно (или обрабатывайте закрытое событие) и вызовите утилизируйте на элемент управления WebBrowser.

8
ответ дан 4 December 2019 в 01:31
поделиться

Вместо этого мы использовали управление WinForm WebBrowser, которое было создано внутри FormsHost в WPF, однако оба работают довольно одинаково с точки зрения пользовательского интерфейса, но мы обнаружили, что WebBrowser WinForms имеет лучшую функциональность и лучшую производительность по сравнению с тем, что предоставлено в WPF.

Вы можете вручную распоряжаться WebBrowser управлением WinForm, который, безусловно, распорядится всеми своими дочерними и свободными ресурсами соответственно, однако, с моим прошлым опытом, WebBrowser WinForm не освобождает 100% своих ресурсов после закрытия, но да, это намного лучше, чем WPF.

1
ответ дан 4 December 2019 в 01:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: