为什么获取 webBrowser 的状态只有在使用另一个线程时才有效
本文关键字:另一个 线程 有效 webBrowser 获取 状态 为什么 | 更新日期: 2023-09-27 18:30:27
我想等到browser.ReadyState == WebBrowserReadyState.Complete
.Webbrowser的事件DocumentCompleted
,但如果页面是使用AJAX加载的,它会在HTML准备就绪时触发,ajax加载的缺失内容目前不可用。我的第一个IDE是:
int[] myFunction() {
int[] values;
while (browser.ReadyState != WebBrowserReadyState.Complete) {
Application.DoEvents();
}
values = get_values_from_browser();
return values;
}
它不能正常工作,返回的速度比应有的要快,而且我在数组中得到了错误的值,例如,所有元素都是一样的。但是,如果我使用Timer
它确实有效(我在数组中获得了正确的值),但我无法从函数返回,因为我不知道何时从函数返回。
计时器为:
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
int[] myFunction() {
int[] values;
timer1.Interval = 1000;
timer1.Tick += new EventHandler(delegate(object o, EventArgs ea)
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
timer1.Stop();
values = get_values_from_browser();
}
});
timer1.Start();
return values;
}
所以我的问题是:为什么它使用新线程(System.Windows.Forms.Timer
)工作,但不能使用主线程中的while
循环? 主情况下的任何Thread.Sleep(x)
都将使其工作。
AJAX 页面是不确定的。 例如,它的JavaScript逻辑可能使用自己的计时器来发出XHR请求,在这种情况下,browser.ReadyState
不会是任何挂起活动的可靠指标。此外,我什至不确定 XHR 要求自己计入browser.ReadyState
. WebBrowser.IsBusy
更有可能解释这一点。附带说明一下,不要使用Application.DoEvents()
,在大多数情况下,这是一种纯粹的邪恶。
若要解决此问题,可以使用异步轮询。我在这里用一些示例代码回答了一个类似的问题:
https://stackoverflow.com/a/20934538/1768303。
在你的第一种方法中,你正在做:
int[] myFunction() {
int[] values;
while (browser.ReadyState != WebBrowserReadyState.Complete) {
values = get_values_from_browser();
Application.DoEvents();
}
return values;
}
这不应该是:
int[] myFunction() {
int[] values;
while (browser.ReadyState != WebBrowserReadyState.Complete) {
Application.DoEvents();
}
values = get_values_from_browser();
return values;
}