I have a for loop:
for (i = 0; i <= 21; i++)
{
webB.Navigate(URL);
}
webB
is a webBrowser control and i
is an int.
I want to wait for the browser to finish navigating.
I found this, however:
void
function, as suggested in this answer
Is there a way to wait while in a for loop?
Assuming you host WebBrowser
in a WinFroms application, you can do it in a loop easily and efficiently, using async/await
pattern. Try this:
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
}
}
Now, it's important to understand that DoNavigationAsync
executes asynchronously. Here's how you'd call it from Form_Load
and handle the completion of it:
void Form_Load(object sender, EventArgs e)
{
var task = DoNavigationAsync();
task.ContinueWith((t) =>
{
MessageBox.Show("Navigation done!");
}, TaskScheduler.FromCurrentSynchronizationContext());
}
I've answered a similar question here.
You don't have to use another void
function. Simply use a lambda
like so:
webB.DocumentCompleted += (sender, e) =>
{
// your post-load code goes here
};
The proper way is to use events.
In your loop, how can you know that that the navigation have completed? maybe you are out of the loop but it is only half way through...
Also, looping while waiting is called Busy waiting and is CPU expensive.
In order to be notified when page is ready, and in the meanwhile keep CPU available for other stuff, use events as @Jashaszun suggested:
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...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With