簡體   English   中英

在多個窗口中使用WPF WebBrowser控件時內存泄漏

[英]Memory leak when using WPF WebBrowser control in multiple windows

我正在開發一個使用WPF WebBrowser控件(System.Windows.Controls.WebBrowser)的項目。 程序的Web瀏覽器元素是用戶可以參與的許多活動之一,並且在單獨的窗口中打開。 在用戶離開瀏覽器之后,窗口關閉,每次用戶返回瀏覽器時都會創建一個新窗口。 我們注意到在我們的程序中出現了嚴重的內存泄漏/性能下降(在初次使用瀏覽器時,使用率從最初的200起大約達到700mb)。 在我們自己的代碼中未能找到任何資源泄漏點后,我決定確定問題是否與我們自己的WebBrowser包裝器控件或WPF控件有關。

我創建了一個新的簡單項目,只包含一個MainWindow和一個WebWindow。 主窗口上的一個按鈕啟動了一個針對gmail的瀏覽器(我們注意到的網站是我們檢查過的少數幾個問題)。 關閉此窗口后,不會釋放資源(任務管理器或Process Explorer中的VM大小沒有減少),並且進程處理的GDI對象數量不會減少(程序以~30開始,打開瀏覽器需要它到~140,關閉瀏覽器后~140仍然打開)。 打開另一個瀏覽器會導致更多句柄,並分配更多資源。 此外,通過在WebBrowser控件上專門調用Dispose()無法解決此問題。 代碼很簡單,如下:

主窗口:

<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的回答更新帖子以指示Dispose()調用 - 甚至在Web瀏覽器控件上調用Dispose()也不會釋放資源]

與大多數WPF控件不同,WebBrowser(因為它繼承自HwndHost)是IDisposable並封裝非托管資源。 與WinForms表單不同,WPF窗口不會自動處理其子項(因為本機WPF控件不會封裝非托管資源,也不需要處理)。

向窗口添加OnClosed覆蓋(或處理Closed事件),並在WebBrowser控件上調用Dispose。

我無法完全解決泄漏,但是,我注意到在處理之前將瀏覽器導航到“about:blank”肯定有助於減少掛起的內存量。

我們改為使用WinForm WebBrowser控件,它是在WPF中的FormsHost中創建的,但是從UI的角度來看兩者的工作方式完全相同,但是我們發現WinForms的WebBrowser與WPF中提供的功能相比具有更好的功能和更好的性能。

你可以手動配置WinForm控件的WebBrowser,它肯定會處理它的所有子節點和相應的免費資源,但是根據我以前的經驗,WinForm的WebBrowser在關閉后不會釋放100%的資源,但是它比WPF好得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM