我可以等待webbrowser使用for循环完成导航吗?
我有一个for循环:
for (i = 0; i <= 21; i++) { webB.Navigate(URL); }
webB
是一个webBrowser控件, i
是一个int。
我想等待浏览器完成导航。
然而,我找到了这个 :
- 我不想使用任何API或插件
- 我不能使用另一个
void
函数,如本答案所示
有没有办法在for循环中等待?
假设您在WinFroms应用程序中托管WebBrowser
,您可以使用async/await
模式轻松高效地循环执行。 试试这个:
async Task DoNavigationAsync() { TaskCompletionSource tcsNavigation = null; TaskCompletionSource tcsDocument = null; this.WB.Navigated += (s, e) => { if (tcsNavigation.Task.IsCompleted) return; tcsNavigation.SetResult(true); }; this.WB.DocumentCompleted += (s, e) => { if (this.WB.ReadyState != WebBrowserReadyState.Complete) return; if (tcsDocument.Task.IsCompleted) return; tcsDocument.SetResult(true); }; for (var i = 0; i <= 21; i++) { tcsNavigation = new TaskCompletionSource (); tcsDocument = new TaskCompletionSource (); this.WB.Navigate("http://www.example.com?i=" + i.ToString()); await tcsNavigation.Task; Debug.Print("Navigated: {0}", this.WB.Document.Url); // navigation completed, but the document may still be loading await tcsDocument.Task; Debug.Print("Loaded: {0}", this.WB.DocumentText); // the document has been fully loaded, you can access DOM here } }
现在,了解DoNavigationAsync
以异步DoNavigationAsync
执行非常重要。 这是你如何从Form_Load
调用它并处理它的完成:
void Form_Load(object sender, EventArgs e) { var task = DoNavigationAsync(); task.ContinueWith((t) => { MessageBox.Show("Navigation done!"); }, TaskScheduler.FromCurrentSynchronizationContext()); }
我在这里回答了类似的问题。
您不必使用其他void
函数。 只需像这样使用lambda
:
webB.DocumentCompleted += (sender, e) => { // your post-load code goes here };
在for循环中使用while循环。
while (webB.ReadyState != tagREADYSTATE.READYSTATE_COMPLETE) { Thread.Sleep(500); }
这将一直等到WebBrowser完全加载页面。
要在一个线程中等待,你可以做这样的事情
System.Threading.Thread.Sleep(2000); //waits 2 seconds
不幸的是,它与导航完成时间没有联系。
正确的方法是使用事件。
在你的循环中,你怎么知道导航已经完成了? 也许你已经离开了循环,但它只有一半…
此外,在等待时循环称为忙等待并且CPU很昂贵 。
为了在页面准备就绪时收到通知,同时保持CPU可用于其他内容,请使用@Jashaszun建议的事件:
void YourFunction() { //Do stuff... webB.DocumentCompleted += (sender, e) => { //Code in here will be triggered when navigation is complete and document is ready }; webB.Navigate(URL); //Do more stuff... }
尝试使用这样的任务:
for (i = 0; i <= 21; i++) { Task taskA = Task.Factory.StartNew(() => webB.Navigate(URL)); taskA.Wait(); }
希望我帮忙。
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load WebBrowser1.Navigate("stackoverflow.com/") End Sub Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted ------yourcode------ End Sub End Class