Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么要使用webBrowser';s状态仅在使用其他线程时有效?_C#_Multithreading_Winforms_Timer_Webbrowser Control - Fatal编程技术网

C# 为什么要使用webBrowser';s状态仅在使用其他线程时有效?

C# 为什么要使用webBrowser';s状态仅在使用其他线程时有效?,c#,multithreading,winforms,timer,webbrowser-control,C#,Multithreading,Winforms,Timer,Webbrowser Control,我想等到browser.ReadyState==WebBrowserReadyState.Complete。有DocumentCompletedWebbrowser的事件,但是如果使用AJAX加载页面,它会在HTML准备就绪时触发,此时AJAX加载的缺失内容不可用。 我的第一个ide是: int[] myFunction() { int[] values; while (browser.ReadyState != WebBrowserReadyState.Complete) {

我想等到
browser.ReadyState==WebBrowserReadyState.Complete
。有
DocumentCompleted
Webbrowser的事件,但是如果使用AJAX加载页面,它会在HTML准备就绪时触发,此时AJAX加载的缺失内容不可用。 我的第一个ide是:

int[] myFunction() {

  int[] values;

 while (browser.ReadyState != WebBrowserReadyState.Complete) {
         Application.DoEvents();
  }
             values = get_values_from_browser();
  return values;
}
它不起作用,返回的时间比它应该的要快,我在数组中得到了错误的值,例如,所有元素都是相同的。但是,如果我使用
计时器
它确实可以工作(我在数组中得到正确的值),但是我不能从函数返回,因为我不知道什么时候从函数返回

计时器为:

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)工作,而不使用主线程中的
循环?在main case中的任何
线程。Sleep(x)
都将使其工作。

在您的第一个方法中:

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;

}AJAX页面是不确定的。例如,它的JavaScript逻辑可能使用自己的计时器发出XHR请求,在这种情况下,
browser.ReadyState
不会是任何未决活动的可靠指示器。 此外,我甚至不确定XHR请求本身是否计入
browser.ReadyState
。更有可能解释这一点。另外,在大多数情况下,不要使用
Application.DoEvents()

要解决这个问题,可以使用异步轮询。我在这里用一些示例代码回答了一个类似的问题:


如果第一段代码是从UI线程运行的,那么您可能会阻止浏览器执行任何工作,因为您占用了该线程,并且从不让任何其他计算在其上发生。事实上,我不是。我正在使用
Application.DoEvents()忘了在这里键入它我不能说我确实知道它为什么不工作,所以这不是你问题的答案。但是,即使第一个解决方案可行,使用计时器的第二个实现也是更好的方法。与第一种解决方案相比,您甚至可以缩短计时器间隔并获得响应的UI。@MotiAzu:第二种解决方案的问题是:在停止
timer1
并调用从webBrowser提取数据的函数后,我想返回到函数。但是我怎么做呢?你可以使用回调委托,这里有一个例子是的,它是。我在SO的文本区域键入代码,然后忘记它。但它无论如何都不起作用,我不知道为什么,但我没有被告知你关于这个话题的答案。这就是为什么我现在才尝试。非常感谢你,伙计。它完全符合我的要求。我已经为此工作了几天,尝试了许多不同的方法,并阅读了有关线程的文章,试图获得一些帮助。祝你今天愉快。如果可以的话,我可以给你50+但是这个问题没有悬赏。@Jack,别担心,很高兴它有帮助。我有一些其他相关的答案,例如,在使用WebBrowser时,您已经是第三次救了我的命。你有那么多技能,伙计。我喜欢那个话题。非常感谢。