Computer User
Computer User

Reputation: 2879

Best way to detect navigation complete in webbrowser control

I have a Form with a webbrowser control and have written code like:

bool DocumentComplete = false;

Form_Activated()
{
  for()
  {
    for()
    {
      //Some operation
      Browser.Navigate(URL);

      while(!DocumentComplete)
      {
        Thread.Sleep(100);
        Application.DoEvents();
      }

      Data = Browser.Document.Body.GetAttribute(some_tag)
      //process "Data" and do other stuff
    }
  }
}

Browser_DocumentComplete()
{
  DocumentComplete = true;
}

I have multiple for loops and many variables that is why I could not paste the "Data" processing code in the Browser_DocumentComplete() itself like:

Browser_DocumentComplete()
{
  Data = Browser.Document.Body.GetAttribute(some_tag)
  //process "Data" and do other stuff
}

Is it the right approach? Any alternative? Someone suggested "Timer" control or "BackgroundWorker" but I wonder how do I modify my code to use Timer without affecting the functionality of the program.

One more question, if I use Thread.Sleep to pause the code execution till the URL completely opens, then does this Thread.Sleep also pauses the navigation process of the webbrowser? I mean is the following code better:

  while(!DocumentComplete)
    Application.DoEvents();

instead of:

      while(!DocumentComplete)
      {
        Thread.Sleep(100);
        Application.DoEvents();
      }

Upvotes: 1

Views: 1951

Answers (1)

Uranus
Uranus

Reputation: 1690

Instead of performing an infinity loop in the GUI thread, you can start it in a background thread and use the EventWaitHandle class to synchronize the background thread with the WebBrowser. Your code might be changed like following:

EventWaitHandle DocumentComplete = new EventWaitHandle(false, EventResetMode.AutoReset);

void Form_Activated(object sender, System.EventArgs e)
{
    new Thread(new ThreadStart(DoWork)).Start();
}

void Browser_DocumentComplete(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
    Data = Browser.Document.Body.GetAttribute(some_tag);
    //process "Data" and do other stuff
    DocumentComplete.Set();
}

void DoWork() {
    for (; ; ) {
        for (; ; ) {
            //Some operation
            Invoke(new NavigateDelegate(Navigate), URL);
            DocumentComplete.WaitOne();
        }
    }
}

void Navigate(string url) {
    Browser.Navigate(url);
}

delegate void NavigateDelegate(string url);

Upvotes: 2

Related Questions