使用多个窗口WPF WebBrowser控件时,内存泄漏 [英] Memory leak when using WPF WebBrowser control in multiple windows

查看:1804
本文介绍了使用多个窗口WPF WebBrowser控件时,内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个项目,它利用了WPF WebBrowser控件(System.Windows.Controls.WebBrowser)的。程序的网络浏览器元件是许多活动用户可接合于一体,并在一个单独的窗口被打开。用户导航从浏览器程后,将窗口关闭,并创建一个新的窗口中的每个用户返回到浏览器时。我们在我们的节目中注意到一个显著内存泄漏/性能降级(使用起床从200〜700MB最初到〜)在继续使用浏览器。没有找到自己的code范围内的资源泄漏的任何点后,我决定,以确定问题是与我们自己的web浏览器包装控件或WPF控件。

I am working on a project that makes use of the WPF WebBrowser control (System.Windows.Controls.WebBrowser). The web browser element of the program is one of many activities the user can engage in, and is opened in a separate window. After the user navigates away from the browser, the window is closed, and a new window is created each time the user returns to the browser. We were noticing a significant memory leak / performance downgrade in our program (usage getting up to ~700mb from ~200 initial) upon continually using the browser. After failing to find any points of resource leaks within our own code, I decided to determine if the issue was with our own WebBrowser wrapper control, or the WPF control.

我创建了一个新的简单的项目只包含一个主窗口和一个WebWindow的。在主窗口上的一个按钮启动针对Gmail的(我们与我们研究了一些发现的最大问题的站点)的浏览器。在关闭这个窗口,没有资源的释放(在任务管理器或Process Explorer中VM不会减少大小)和GDI对象数量的进程句柄没有减少(程序开头〜30,打开浏览器需要它〜140,并关闭浏览器〜140后仍然是开放的)。打开另一个浏览器会导致更多的把手,将分配更多的资源。此外,这个问题不是由WebBrowser控件上专门调用Dispose()固定。在code是简单,如下:

I created a new simple project consisting of only a MainWindow and a WebWindow. A button on the main window launches a browser directed at gmail (the site we noticed the biggest issue with of the few we examined). Upon closing this window, there is no freeing of resources (no reduction in VM size in Task Manager or Process Explorer) and the number of GDI objects the process has handles to does not decrease (the program starts with ~30, opening the browser takes it to ~140 and after closing the browser ~140 are still open). Opening another browser causes more handles, and more resources to be allocated. Furthermore, this problem is not fixed by specifically calling Dispose() on the WebBrowser control. The code is simple, and is as follows:

主窗口:

<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:

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>

相关code:

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控件这个问题?

Has anyone else encountered this issue using the WPF WebBrowser control?

[更新:更新后,表示Dispose()方法调用按itowlson的答案 - 即使是在Web浏览器控件调用Dispose()不释放资源]

[UPDATE: Updated post to indicate Dispose() call as per itowlson's answer - even calling Dispose() on the web browser control does not free the resources]

推荐答案

与大多数WPF控件,web浏览器(因为它是从HwndHost继承)是IDisposable接口和封装非托管资源。 WPF窗口,不像WinForms的形式,做的的自动处理其子(因为本地WPF控件不封装非托管资源,不需要处置)。

Unlike most WPF controls, WebBrowser (because it inherits from HwndHost) is IDisposable and encapsulates unmanaged resources. The WPF Window, unlike the WinForms Form, does not automatically dispose its children (because native WPF controls do not encapsulate unmanaged resources and do not require disposal).

添加OnClosed覆盖到你的窗口(或处理Closed事件),并调用Dispose WebBrowser控件。

Add an OnClosed override to your window (or handle the Closed event), and call Dispose on the WebBrowser control.

这篇关于使用多个窗口WPF WebBrowser控件时,内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆