.NET Webbrowser Control and Dispose()
本文关键字:Dispose and Webbrowser Control NET | 更新日期: 2023-09-27 18:26:30
我知道这是一个热门话题,有很多问题和答案,但我仍然没有找到以下问题的解决方案:
我有一个多选项卡应用程序。每个选项卡上都有一个Webbrowser控件。由于Web浏览器为每个新选项卡占用更多的内存,并且在选项卡关闭时无法释放这些内存,我决定在选项卡关闭事件处理程序中创建Webbrowser.Dispose()。这对我的记忆泄露有所帮助。关闭后,所有使用过的RAM现在都是空闲的。
但这引发了一个新问题:在第一个Dispose()之后,似乎所有其他Webbrowser对象的会话都被破坏了。通常我只登录第一个网络浏览器。如果我添加了几个选项卡,我通常会自动登录。在第一次Dispose()之后,这就不起作用了,我必须登录每个新的选项卡
我试图保留旧的cookie,并用新的网络浏览器再次发送,但这并没有解决问题。似乎已被摧毁。
这似乎是GarbageCollector的问题。您可以尝试使用System.GC.Collect()的脏方法,只是调用GarbageCollector来释放内存,但这不是解决问题的好方法。
关于你所说的,这似乎是一个指针问题。如果您将Connection声明为全局变量,则必须先将连接从选项卡分离,然后才能关闭/释放选项卡本身。事件Me.关闭将帮助您做到这一点。如果指针保持打开,则选项卡作为对象仍然连接在连接上,并且GC不会清除(如果/当时,则不会真正清除)。
如果你能澄清你复制/引用连接的方式,我可以给出更详细的答案。
编辑:经过一段时间的研究,我的担忧变成了现实——IE下的缓存有问题(据我所知,>5)。http://social.msdn.microsoft.com/Forums/ie/en-US/88c21427-e765-46e8-833d-6021ef79e0c8/memory-leak-in-ie-webbrowser-control
建议是:
-
手动调用GarbageCollector
-
限制MemUsage(可能导致应用程序崩溃,也只是将页面写入磁盘)
-
关于:blanc覆盖缓存项
-
调用C++方法来覆盖缓存(WinINet-我发现的所有结果都导致了一些ProtectedMemory错误-也许这个C#WebBrowser控件:清除缓存而不清除cookie有效)
-
使用C++和WinINet(我不知道任何真正的.Net实现,它可能也有内存泄漏)
-
使用IE的替代品,如gecko(Mozilla)-https://bitbucket.org/geckofx/
所有WebBrowser实例在每个进程的基础上共享会话。根据EricLaw对类似问题的回答,似乎不可能将会议分开。我相信孙在微软担任IE项目经理时的说法。
然而,如果你仍然想尝试一些技巧,你可以看看CoInternetGetSession。首先,尝试保存并保留返回的对IInternetSession的引用。此外,您可以考虑注册自己的URL命名空间(RegisterNameSpace),并实现一个可插入的协议处理程序,该处理程序最终可能会允许否决此限制。
当然,这听起来有些过头了,而且很可能根本于事无补。一个干净的解决方案可能是重新设计逻辑以消除cookie并通过URL传递状态。
已编辑:另一个想法是,尝试将WebBrowser实例导航到(比如)"about:black"并等待DocumentComplete事件,然后使用Dispose()实际处理它。
感谢您的回答。我在这里检查了一下:
手动调用GC:
- 只有当我以前在中使用Webbrowser.Dispose()时才有帮助。但由于会话问题,这不是一个解决方案
限制内存使用:
- 不是解决方案。这个程序应该运行一整天,有很多选项卡的打开和关闭。如果我不能清理用过的内存,几个小时后内存使用量会太多
关于:空白:
- 我在关闭选项卡时调用了about:black。在该URL发生DocumentLoaded之后,我处理了Webbrowser。与直接调用Dispose的过程相同。会话中断
其他组件:
- 我需要在任何情况下都有IE控件,因为(专有)互联网应用程序只支持IE 8及更高版本
"使用c++和WinInet":
- 我可以在我的.net程序中使用C++浏览器吗?我无法将整个程序切换到C++。这对我来说不是一个解决方案
总结:
我的应用程序在没有Dispose的情况下运行良好,但存在内存使用量增加的问题。如果我们能找到解决方案(这似乎是不可能的),那将是最好的解决方案。
对我来说,唯一可以接受的"变通方法"是重用"关闭的"网络浏览器。详细说明:在每次关闭选项卡时,我都会将Webbrowser添加到List中,而不是Dispose它们。当我需要一个新的选项卡时,我会从列表中取出第一个,然后重新使用它,然后导航到新的URL:我试过了,但会话似乎也有同样的问题。重复使用的选项卡中的会话似乎又是新的。但我真的不明白为什么。。。对此也有建议吗?
另一种解决方法是强制每个Webbrowser对象都是一个实例。这可能吗?