tags:

views:

50

answers:

1

When I do the following (Actually I repeat the same whole code with different web pages):

        Navigator nav;
        nav = new Navigator();
        nav.Browser.Navigate("http://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-keywords=&field-author=&field-title=&field-isbn=0471848573+&field-publisher=&node=&field-p_n_condition-type=&field-feature_browse-bin=&field-binding_browse-bin=&field-subject=&field-language=&field-dateop=&field-datemod=&field-dateyear=&sort=relevanceexprank&Adv-Srch-Books-Submit.x=18&Adv-Srch-Books-Submit.y=4");
        while (nav.Browser.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();
        nav.Dispose();

Navigator is a Form that contains a public WebBrowser and that's it. You can test it yourself and I think the same will happen, but it doesn't happen every single time. You might need to put it in a loop and repeat it a few times for the problem to happen.

+2  A: 

Make your Navigator form look like this:

public partial class Navigator : Form {
    private bool done;

    public Navigator() {
        InitializeComponent();
        Browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Browser_DocumentCompleted);
    }
    void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
        if (e.Url == Browser.Url) done = true;
    }
    public bool Completed {
        get { return done; }
    }
}

And your loop like this:

        Navigator nav;
        nav = new Navigator();
        nav.Browser.Navigate("http://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&unfiltered=1&field-keywords=&field-author=&field-title=&field-isbn=0471848573+&field-publisher=&node=&field-p_n_condition-type=&field-feature_browse-bin=&field-binding_browse-bin=&field-subject=&field-language=&field-dateop=&field-datemod=&field-dateyear=&sort=relevanceexprank&Adv-Srch-Books-Submit.x=18&Adv-Srch-Books-Submit.y=4"); //        http://msn.com"); //stackoverflow.com/questions/3661536/while-true-application-doevents-doesnt-know-when-the-program-finishes");
        this.Enabled = false;
        while (!nav.Completed) Application.DoEvents();
        this.Enabled = true;
        nav.Dispose();
Hans Passant
That solved it. But why?
jsoldi
Hans, shouldn't he use a `using` block around `nav`?
John Saunders
You are pulling the rug out from under IE *before* it is done. Note the test in the DocumentCompleted event.
Hans Passant
I removed the `this.Enabled = false` and still worked. Is it really necessary?
jsoldi
Yes, this is *very* necessary. Calling DoEvents() while the user interface is still enabled is very dangerous. The user could close the form or click the button again while your code is looping. That never comes to a good end.
Hans Passant
I'm pretty stunned that none of my answers has been helpful so-far. What's the problem with them?
Hans Passant
Wait. That didn't solved it. That while should have beenn `while(!nav.Completed) Application.DoEvents();` instead of `while(nav.Completed) Application.DoEvents();`. If I put it this way the problem persists.
jsoldi
Crud, typo. Works on my machine.
Hans Passant
jsoldi
There is no ReadyState check in my code. The DocumentCompleted event is important.
Hans Passant
I added it. Just to be 100% sure the page has loaded.
jsoldi
And yes, checking `ReadyState` IS the cause of the problem. Just removed it from my real application and everything works fine now. Isn't it weird?
jsoldi
Hans, it took a few Posts but you finally got his program working. Cheers.
Henk Holterman
ReadyState doesn't actually tell you that the browser is ready, it only tells you that the frame is complete. There are multiple frames, this Amazon link behaves particularly crazy in the regular browser. If you keep your original code and just remove the ReadyState check then you'll abort the browser before it really got anywhere.
Hans Passant
@Henk: yes, that was hard work. Thanks for the sympathy :)
Hans Passant
Hans Passant