加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在多个窗口中使用WPF WebBrowser控件时出现内存泄漏

发布时间:2020-12-15 06:22:55 所属栏目:百科 来源:网络整理
导读:我正在使用一个使用 WPF WebBrowser控件(System. Windows.Controls.WebBrowser)的项目.程序的Web浏览器元素是用户可以从事的许多活动之一,并在单独的窗口中打开.用户从浏览器导航后,窗口关闭,每次用户返回浏览器时都会创建一个新窗口.持续使用浏览器后,我们
我正在使用一个使用 WPF WebBrowser控件(System. Windows.Controls.WebBrowser)的项目.程序的Web浏览器元素是用户可以从事的许多活动之一,并在单独的窗口中打开.用户从浏览器导航后,窗口关闭,每次用户返回浏览器时都会创建一个新窗口.持续使用浏览器后,我们注意到我们的程序中的内存泄漏/性能降级显着(使用率从?200初始达到?700MB).在我们自己的代码中找不到任何资源泄漏点后,我决定使用我们自己的WebBrowser包装器控件或WPF控件来确定问题.

我创建了一个新的简单项目,只有一个MainWindow和一个WebWindow.主窗口上的一个按钮启动了一个指向gmail的浏览器(我们注意到我们检查过的最少的问题).关闭此窗口时,不会释放资源(任务管理器或进程资源管理器中的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,并且封装了非托管资源. WPF窗口与WinForms窗体不同,它不会自动处理其子项(因为本机WPF控件不会封装非托管资源,也不需要处理).

将一个OnClosed覆盖添加到您的窗口(或处理Closed事件),并在WebBrowser控件上调用Dispose.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读