等待 WebBrowser 完成加载时 Application.DoEvents() 出现问题

Posted

技术标签:

【中文标题】等待 WebBrowser 完成加载时 Application.DoEvents() 出现问题【英文标题】:Problem with Application.DoEvents() while waiting for WebBrowser to finish loading 【发布时间】:2011-10-11 07:49:06 【问题描述】:

我正在尝试加载 WebBrowser 内容,然后我想添加一些文本并滚动到底部。

这是我的代码示例:

webBrowser1.Url = new System.Uri("file:///" + filePath);
webBrowser1.Document.Body.Innerhtml += text;
webBrowser1.Document.Body.ScrollTop = webBrowser1.Document.Body.ScrollRectangle.Height;

当我运行它时,有一个未处理的异常“对象引用未设置为对象的实例”。或者,当我注释行滚动时,文本会添加到 WebBrowser 的先前内容中,然后导航到新内容。

所以在我的示例代码的第一行之后,我放了:

while (webBrowser1.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();

但它搞砸了一切。我的应用程序正在做一些非常奇怪的事情,例如多次调用同一个方法,而实际上应该调用一次。

有什么解决办法吗?

【问题讨论】:

您是否有任何在后台运行的计时器或异步方法可能会影响这一点? webBrowser1 对象上是否有任何事件会被调用,比如 OnReadyStateChanged? 【参考方案1】:

我认为您实际上想订阅DocumentCompleted 事件。Application.DoEvents 仅处理待处理的 Windows 消息循环项。

在任何一种情况下,请确保在使用之前了解possible drawbacks 调用DoEvents

【讨论】:

是的,处理可能会导致重入问题,***Exception(以防 DoEvents 将调用再次调用 DoEvents 的方法)和其他有趣的东西。最好在调用它之前确保您了解DoEvents 的工作原理。 绝对。我认为对这种方法的混淆部分源于这样一个事实,即曾经流行的 Visual Basic 6 有一个名称完全相同的方法,它被用作多线程的不良替代品。 嗯,我没有用VB6写,但它仍然用作替代品。实际上结果相同:) 有点离题,但无论如何。 Windows 上的低级本机编程中有类似的东西,称为“用户 APC”或异步过程调用。有时有用,但也很危险。【参考方案2】:

DoEvents() 在这里是一个糟糕的解决方案。您应该使用显式线程或BackgroundWorker 来加载页面并让 UI 线程来处理其他内容。

【讨论】:

WebBrowser 无法在 MTU 上运行,BackgroundWorker 仅创建 MTU 线程 @odyodyodys 你的意思是 MTA - 多线程单元吗?在这种情况下,像这样使用这个组件是个坏主意。也许它允许显式设置内容(而不是设置 Uri)或以某种方式使内容下载异步?

以上是关于等待 WebBrowser 完成加载时 Application.DoEvents() 出现问题的主要内容,如果未能解决你的问题,请参考以下文章

单击按钮后等待加载页面

MFC WebBrowser判断网页加载完成

等待 ajax 更改时 Webbrowser 出错

webbrowser轻松实现自动填表

wpf webBrowser 禁用超链接

检测 WebBrowser 完整页面加载