Can I wait for a webbrowser to finish navigating, using a for loop?

c#, webbrowser-control

Solution

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.

Problem

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: - I don't want to use any APIs or addins - I can't use another `void` function, as suggested in this answer Is there a way to wait while in a for loop?

Original source

Related problems