Winforms:消除WebBrowser的GDI Objects泄露

         WinformsWebBrowser是一个经常被使用的控件,用来浏览网页。可是很多程序员发现WebBrowser会有GDI Objects泄露。

一、             问题重现步骤

1.       新建一个Winforms项目;

2.       添加一个新Form,命名为FormWebBrowser

3.       FormWebBrowser中添加一个WebBrowser,并为属性Url设置一个有效的网址;

4.       回到Form1,在上面添加一个按钮;

5.       双击按钮,进入代码编辑窗口;

6.       button1Click添加事件处理器:

private void button1_Click(object sender, EventArgs e)

{

    FormWebBrowser form = new FormWebBrowser();

    form.ShowDialog();

}

7.       编译运行;

8.       打开任务管理器。如果进程(Processes)页面没有GDI Objects的列,点击菜单视图 View->选择列(Select Column…)。在弹出的对话框中,选择GDI Objects

9.       点击button1,这样FormWebBrowser就会弹出来。关掉FormWebBrowser,回到Form1。再点击button1。这样重复弹出FormWebBrowser再关掉。

10.   在步骤9中,注意每次关掉FormWebBrowserGDI Objects数目。我们会注意到GDI Objects数目会一直升高。这就是GDI Objects的症状。

二、             原因分析

为了正确显示网页的内容,WebBrowser会创建一些GDI的对象。GDI对象不是托管资源,因此当我们不再需要这些资源时,我们应该显示释放这些资源。WebBrowser提供了Dispose函数,在WebBrowser不再使用的时候,我们应该调用Dispose函数。

三、             建议

既然出现GDI Objects泄露的原因是没有调用WebBrowser.Dispose(),我们就应该在合适的时候调用这个方法。显然,我们在FormWebBrowser消失的时候,我们不会再使用WebBrowser,这个时候就可以调用该方法。也就是我们可以在FormWebBrowserClosed事件处理器里调用WebBrowser.Dispose

事实上Form也有Dispose方法。在Form.Dispose里,Winforms会去调用它所有子控件的Dispose方法。因此,一个更安全的办法就是当FormWebBrowser不再使用的时候,调用FormWebBrowser.Dispose

C#提供了using的关键词。使用这个关键词创建的对象,.NET会确保在这些对象不再使用的时候会调用它们的Dispose。这样会比我们自己调用Dispose会更安全。

基于上面的分析,我们建议的办法是:我们用using关键词创建FormWebBrowser 对象。这样当我们关掉一个FormWebBrowser的时候,我们会确保它的Dispose会被调用。这样WebBrowserDispose也会被调用,GDI的资源也就随之释放,也就没有GDI的泄露了。

参考代码如下:

    private void button1_Click(object sender, EventArgs e)

    {

        using (FormWebBrowser form = new FormWebBrowser())

            form.ShowDialog();

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值