gpt4 book ai didi

c# - 在多个窗口中使用 WPF WebBrowser 控件时发生内存泄漏

转载 作者:可可西里 更新时间:2023-11-01 09:08:36 24 4
gpt4 key购买 nike

我正在开发一个使用 WPF WebBrowser 控件 (System.Windows.Controls.WebBrowser) 的项目。该程序的 Web 浏览器元素是用户可以参与的众多事件之一,并在单独的窗口中打开。用户离开浏览器后,窗口关闭,每次用户返回浏览器时都会创建一个新窗口。我们注意到在持续使用浏览器时,我们的程序出现了显着的内存泄漏/性能下降(使用量从最初的 ~200mb 上升到~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>

按钮点击:

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 窗口不会自动处理其子项(因为 native WPF 控件不封装非托管资源并且不需要处理)。

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

关于c# - 在多个窗口中使用 WPF WebBrowser 控件时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2069314/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com