简体   繁体   中英

WebBrowser DocumentCompleted event fired more than once

I've been researching this stuff and everyone seems to agree that the solution is to check the ReadyState of the Web Browser until is set to Complete.

But actually the event is sometimes fired with the ReadyState set to Complete several times.

I don't think there is a solution with that crappy .NET WebBrowser, but there might be one if I use the underlying DOM component.

Only problem is, I have no idea how do access the DOM component behind the WebBrowser that fires the DocumentCompleted event.

DocumentCompleted will fire for each frame in the web page. The hard way is to count off the frames, shows you how to access the DOM:

private int mFrameCount;

private void startNavigate(string url) {
  mFrameCount = 0;
  webBrowser1.Navigate(url);
}

private void DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
  mFrameCount += 1;
  bool done = true;
  if (webBrowser1.Document != null) {
    HtmlWindow win = webBrowser1.Document.Window;
    if (win.Frames.Count > mFrameCount && win.Frames.Count > 0) done = false;
  }
  if (done) {
    Console.WriteLine("Now it is really done");
  }
}

The easy way is to check the URL that completed loading:

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    if (e.Url.Equals(webBrowser1.Url)) {
        Console.WriteLine("Now it is really done");
    }
}

This would probably happen if the page uses Javascript or <meta refresh> to redirect to another page.

If so, there's no good workaround.

I can't find anything that will give 100% certainty. Mentioned example (e.Url.Equals(webBrowser1.Url)) may work for a simple WebBrowser.Navigate(url), however, in my case I click nodes in code to open new frames in existing frames. Mostly the number of times "Navigating" and "DocumentCompleted" fire will be the same, but again NOT always. "isBusy = false" and "ReadyState = Complete" will always be the case when it's finished (at least so far) but it will also a few times have this state when it's still loading. Counting frames also seems useless for me, in one case DocumentCompleted is fired 23 times, however, all frames and sub(-sub-sub and so on) frames are 14 in total.

The only thing that seems to work is wait a short period (1 or 2 seconds?) to see if anything happens (any events fired, any state changes).

Hmm, I found another solution for me. Often we're not interested in the whole page being loaded, often we want certain elements to exists. So after each DocumentCompleted and when "isBusy = false" and "ReadyState = Complete" we can search the DOM if this element exists.

In my experience it's impossible to tell when a web page has finished loading until DocumentCompleted hasn't fired for a while. So I refresh a timer for around 1000ms every time the DocumentCompleted event triggers. Then when the timer times out I process the web page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM