User6996
User6996

Reputation: 3003

BackgroundWorker + WebBrowser

I have tried to navigate through a couple of web pages using an backgroundworker & webbrowser. Im using this function which it doesnt work. Im not sure what is going wrong here.

I see only the MessageBox.Show(arr[0]); nothing else. the webbrowser doesnt change too

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    string[] arr = { "http://stackoverflow.com/", "http://www.codeproject.com/", "http://www.codeplex.com/" };
    for (int i = 0; i < 3; i++)
    {
        MessageBox.Show(arr[i]);
        bB_checker.Invoke((EventHandler)delegate { bB_checker.Navigate(arr[i]); });
        while (bB_checker.ReadyState != WebBrowserReadyState.Complete)
        {
            //  System.Threading.Thread.Sleep(100);
            Application.DoEvents();
        }
    }
}

Upvotes: 0

Views: 2994

Answers (3)

Hans Passant
Hans Passant

Reputation: 941457

Never implement BGW without checking the e.Error property in the RunWorkerCompleted event handler:

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        if (e.Error != null) MessageBox.Show(e.Error.ToString());
    }

The somewhat mysterious invalid cast exception is caused by using the ReadyState property on a worker thread. WebBrowser is not threadsafe. Check this answer for a way to create a WB on a worker thread.

That's not however a good way if you need to keep the browser visible to the user. You'll have to give up on using threading in that case. Not a real problem, just count up the array index in the DocumentCompleted event handler. Albeit that it makes little sense to flash these web pages.

Upvotes: 4

Tedd Hansen
Tedd Hansen

Reputation: 12314

Ensure that AllowNavigation property i set to True. See http://dotnetpulse.blogspot.com/2006/07/why-wont-webbrowser-navigate.html

Upvotes: 0

shf301
shf301

Reputation: 31394

You can't access the WebBrowser control's property from outside it's UI thread. Remember a property is a method under the covers, so it is the same reason that you must use Invoke to call Navigate.

The Application.DoEvents() isn't necessarily (and I'm not sure will even work) since the background worker is running on a different thread than your UI thread.

Also rather than polling the WebBrowser's state, use the DocumentCompleted event to get your asynchronous notification:

 int i = 0;
 string[] arr = { "http://stackoverflow.com/", "http://www.codeproject.com/", "http://www.codeplex.com/" };

 protected override void OnShown(EventArgs e)
 {
     base.OnShown(e);
     bB_checker.DocumentCompleted += bB_checker_DocumentCompleted;
     bB_checker.Navigate(arr[0]);
 }

 void bB_checker_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
 {
     i++;
     if (i < arr.Length)
        bB_checker.Navigate(arr[i]);
 }

Upvotes: 1

Related Questions