为什么获取 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)都将使其工作。

为什么获取 webBrowser 的状态只有在使用另一个线程时才有效

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;

}