我有一个 for 循环:
for (i = 0; i <= 21; i++)
{
webB.Navigate(URL);
}
webB
是一个 webBrowser 控件并且i
是一个 int。
我想等待浏览器完成导航。
但是,我发现了这个:
- 我不想使用任何 API 或插件
- 如this answer中所建议,我不能使用其他
void
功能
有没有办法在 for 循环中等待?
我有一个 for 循环:
for (i = 0; i <= 21; i++)
{
webB.Navigate(URL);
}
webB
是一个 webBrowser 控件并且i
是一个 int。
我想等待浏览器完成导航。
但是,我发现了这个:
void
功能有没有办法在 for 循环中等待?
假设您托管在 WinFroms 应用程序中,您可以使用模式WebBrowser
轻松有效地循环执行它。async/await
尝试这个:
async Task DoNavigationAsync()
{
TaskCompletionSource<bool> tcsNavigation = null;
TaskCompletionSource<bool> 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<bool>();
tcsDocument = new TaskCompletionSource<bool>();
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
异步执行很重要。以下是您如何调用它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
};
正确的方法是使用事件。
在你的循环中,你怎么知道导航已经完成?也许你不在循环中,但它只是通过了一半......
为了在页面准备好时收到通知,同时保持 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 循环中使用这个 while 循环。
while (webB.ReadyState != tagREADYSTATE.READYSTATE_COMPLETE)
{
Thread.Sleep(500);
}
这将等到 WebBrowser 完全加载页面。
尝试使用这样的任务:
for (i = 0; i <= 21; i++)
{
Task taskA = Task.Factory.StartNew(() => webB.Navigate(URL));
taskA.Wait();
}
希望我有所帮助。
要在线程中等待,您可以执行以下操作
System.Threading.Thread.Sleep(2000); //waits 2 seconds
不幸的是,它与导航完成时间无关。
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