title: Waiting for event within a function
body: <p>My goal:<br>
  User should be able to get the html source of a page, when clicked on a button. This event opens a new form with a geckoWebBrowser component and navigates to a given url.
  Once this is done it fires a documentCompleted event.
  Then I can start loading the DOM.</p>
  
  <p>The problem:<br>
  While the loading of the page needs time, I have to wait untill in the second form class the DOM (or just the value of a div) is loaded. This is exactly the problem! Every wait or loop stucks the second form (geckoBrowser) so I can't get the value.</p>
  
  <p>This is the code of the first form:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using System.Threading;
  
  namespace mozillaFirefox2
  {
  public partial class Form1 : Form
  {
  
      string source = "";
  
      public Form1()
      {
          InitializeComponent();
      }
  
      private void button1_Click(object sender, EventArgs e)
      {
          //BackgroundWorker bw = new BackgroundWorker();
          //bw.DoWork += new DoWorkEventHandler(bw_DoWork);
  
          Browser br = new Browser();
          //object parameters = br;
          //bw.RunWorkerAsync(parameters);
          br.navigate("http://www.google.com/#hl=en&amp;q=superman&amp;aq=f&amp;aqi=&amp;oq=&amp;fp=1&amp;cad=b");
  
          Thread th = new Thread(delegate() { this.dw(br); });            
          th.Start();
          th.Join(2000);
  
          richTextBox1.AppendText(br.GetSource + "\n");            
      }
  
      private void dw(Browser br)
      {
          while (br.workDone == false)
          {
              //donothing
          }
          source = br.GetSource;
      }
  
      //void bw_DoWork(object sender, DoWorkEventArgs e)
      //{
      //    Browser br = (Browser)e.Argument;
      //    while (br.workDone == false)
      //    {
      //        //donothing
      //    }
      //    richTextBox1.AppendText(br.GetSource + "\n");
      //}
  }
  }
  </code></pre>
  
  <p>This is the second:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Data;
  using System.Drawing;
  using System.Linq;
  using System.Text;
  using System.Windows.Forms;
  using System.Threading;
  
  namespace mozillaFirefox2
  {
  //Declare a delegate who points to a function / signature
  public delegate void GotDataEventHandler(object sender, EventArgs e); 
  
  
  class Browser : Form
  {
      public event GotDataEventHandler GotData;
  
      private System.ComponentModel.IContainer components = null;
  
      protected override void Dispose(bool disposing)
      {
          if (disposing &amp;&amp; (components != null))
          {
              components.Dispose();
          }
          base.Dispose(disposing);
      }
  
      #region Windows Form Designer generated code
  
      /// &lt;summary&gt;
      /// Required method for Designer support - do not modify
      /// the contents of this method with the code editor.
      /// &lt;/summary&gt;
      private void InitializeComponent()
      {
          this.geckoWebBrowser1 = new Skybound.Gecko.GeckoWebBrowser();
          this.SuspendLayout();
  
          // 
          // geckoWebBrowser1
          // 
          this.geckoWebBrowser1.Location = new System.Drawing.Point(14, 4);
          this.geckoWebBrowser1.Name = "geckoWebBrowser1";
          this.geckoWebBrowser1.Size = new System.Drawing.Size(261, 67);
          this.geckoWebBrowser1.TabIndex = 2;
          this.geckoWebBrowser1.DocumentCompleted += new EventHandler(geckoWebBrowser1_DocumentCompleted);
          //Never forget this. Otherwise this error is raised "Cannot call Navigate() before the window handle is created"
          this.geckoWebBrowser1.CreateControl();
          // 
          // Form1
          // 
          this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
          this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
          this.ClientSize = new System.Drawing.Size(788, 577);
          this.Controls.Add(this.geckoWebBrowser1);
          this.Name = "Form1";
          this.Text = "Form1";
          this.ResumeLayout(false);            
  
      }
  
      #endregion
  
      public Skybound.Gecko.GeckoWebBrowser geckoWebBrowser1;
  
      public string source = "";
  
      public bool workDone = false;
  
      public bool navCall = false;
  
      [STAThread]
      public Browser()
      {
          Skybound.Gecko.Xpcom.Initialize(@"C:\Program Files\Mozilla-Gecko ActiveX WebBrowserControl\xulrunner-1.9.1.2.en-US.win32\xulrunner");
          Skybound.Gecko.GeckoPreferences.User["general.useragent.override"] = "Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)";
          this.InitializeComponent();                        
          this.Show();
      }
  
  
      public delegate void NavigationHandler(string url);
      public void navigate(string url)
      {
          if (this.InvokeRequired)
          {
              object[] parameters = { url };
              this.geckoWebBrowser1.Invoke(new NavigationHandler(navigate), parameters);
          }
          else
          {
              navCall = true;
              this.geckoWebBrowser1.Navigate(url);
          }
      }
  
      public string GetSource
      {
          get { return source; }
      }
  
      public string getSource()
      {
          return source;
      }
  
      public void geckoWebBrowser1_DocumentCompleted(object sender, EventArgs e)
      {
          if(navCall == true){
              source = this.geckoWebBrowser1.Document.GetElementById("res").InnerHtml.ToString();
              workDone = true;
              navCall = false;
  
              //
              GotDataEventHandler gd;
              lock (this)
              {
                  gd = GotData;
              }
              if (gd != null)gd(this, EventArgs.Empty);
  
          }
      }
  }
  }
  </code></pre>
  
  <p>Now I should be able to just wait till I get an answer within the button1_Click function or catch the event within this function or a function on the second form so I can return this (than the code will wait by itself). Don't know how to do this.</p>