.NET Web浏览器控制和处理()

时间:2013-08-05 10:18:19

标签: c# .net session webbrowser-control dispose

我知道这是一个热门讨论的主题,有很多问题和答案,但我仍然找不到解决以下问题的方法:

我有一个多标签应用程序。每个选项卡上都有一个Webbrowser控件。 随着webbrowsers为每个新选项卡占用更多内存,并且它们不会在tab-close上释放这些内存,我决定在tab close事件处理程序中创建一个Webbrowser.Dispose()。这有助于我解决内存泄漏问题。关闭后,所有使用过的RAM现在都是免费的。

但是这引起了一个新问题:在第一个Dispose()之后,似乎会破坏所有其他Webbrowser对象的会话。 通常我只登录frist webbrowser。如果我添加几个标签,我通常会自动登录。在第一个Dispose()之后,这不再起作用了,我必须登录每个新的Tab。

我尝试保留旧的Cookie并使用新的webbrowser再次发送它们,但这并没有解决问题。似乎被摧毁了。

3 个答案:

答案 0 :(得分:2)

所有WebBrowser实例基于每个进程共享会话。根据{{​​3}}对类似问题的看法,似乎无法将会议分开。我相信Eric的陈述是EricLaw's answer

如果你还想尝试一些黑客攻击,你可以看一下he worked as IE program manager at Microsoft。首先,尝试保存并保留返回的CoInternetGetSession引用。此外,您可以查看注册自己的URL命名空间(IInternetSession)并实现可插拔协议处理程序,最终可能会否决此限制。

当然,这听起来像是一种矫枉过正,很可能根本无济于事。一个干净的解决方案可能是重新设计逻辑以摆脱cookie并通过URL传递状态。

已编辑:另一个想法是,在使用Dispose()实际处理它之前,尝试将WebBrowser实例导航到(例如)“about:blank”并等待DocumentComplete事件。

答案 1 :(得分:2)

这似乎是一个GarbageCollector问题。您可以尝试使用 System.GC.Collect()的脏方法,只需调用GarbageCollector释放内存,但这不是解决问题的好方法。

你所说的,这似乎是一个指针问题。 如果您将Connection声明为全局变量,则必须从选项卡中分离连接,因为您可以关闭/处置它所选择的选项卡。事件 Me.Closing shuld帮助您这样做。 如果指针保持打开状态,则作为对象的选项卡仍然连接在连接上,并且(如果/当时)不会真正保护不被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(可能导致应用程序崩溃,也只是将页面写入磁盘)

  • about:blanc to override cache-entries

  • 调用C ++方法来覆盖缓存(WinINet - 我发现的所有内容都导致了一些ProtectedMemory-Errors - 也许这个C# WebBrowser control: Clearing cache without clearing cookies有效)

  • 使用C ++和WinINet(我不知道任何真正的.Net实现,也可能有内存泄漏)

  • 使用IE的替代品,如gecko(Mozilla) - https://bitbucket.org/geckofx/

答案 2 :(得分:1)

感谢您的回答。这是我检查的内容:

手动调用GC:

  • 只有在我之前使用Webbrowser.Dispose()时才有用。 但由于会话问题,这不是解决方案。

限制内存使用:

  • 不是解决方案。这个程序应该运行一整天,有很多打开和关闭选项卡。如果我无法清理用过的内存,几个小时后内存使用量就会太多了。

关于:空白:

  • 我打电话给:关闭标签时为空白。在为此URL发生DocumentLoaded之后,我处理了Web浏览器。与直接调用Dispose相同的过程。会议失败。

其他组成部分:

  • 我需要在每种情况下都有IE控件,因为(专有)互联网应用程序仅支持IE 8及更高版本。

“使用c ++和WinInet”:

  • 我可以在.net程序中使用C ++浏览器吗?我无法将整个程序切换到C ++。这对我来说不是一个解决方案。

总结:

我的应用程序在没有Dispose的情况下工作正常但存在内存使用量增加的问题。如果我们能找到一个解决方案(这似乎是不可能的),那将是最好的解决方案。

对我来说唯一可接受的“解决方法”是重复使用“封闭式”网络浏览器。详细信息:在每个选项卡关闭时,我将Webbrowser添加到List而不是Dispose它们。当我需要一个新选项卡时,我从列表中取出第一个并重新使用它并导航到新URL:我试了一下,但似乎会话存在同样的问题。重用标签中的会话似乎又是新的。但我真的不明白为什么......也有这方面的建议吗?

另一种解决方法是强制每个Webbrowser对象都是单个实例。这可能吗?