Why is WebBrowser_DocumentCompleted() firing twice?

Every time a frame loads, the event is fired.

Also, before you even go there, the IsBusy property will only be True whilst the first frame has not loaded.

void BrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
  if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
    return; 

  //The page is finished loading 
}

You can check the WebBrowser.ReadyState when the event is fired:

if (browser.ReadyState != WebBrowserReadyState.Complete)
    return;

ReadyState will be set to Complete once the whole document is ready.