title: Managing multiple threads and general code flow
body: <p>There's a lot of code here so let me explain quickly what it is <em>supposed</em> to do.</p>
  
  <h2>Expected flow:</h2>
  
  <ol>
  <li><code>GetScenarios();</code> opens a SQL connection and starts a <code>while</code> loop to loop through a <code>Scenarios</code> database.</li>
  <li>When the first item in the database is selected, run <code>TestScenarios()</code> on it.</li>
  <li><code>TestScenarios()</code> reads some of the item's XML values, one of which is <code>Url</code>, and then opens up the <code>Url</code> in a <code>WebBrowser</code> control.</li>
  <li>When that webpage is open, some Javascript is injected and invoked in order to <code>click</code> (test) an element on the page.</li>
  <li>The if statement <code>TestUrl.Equals(expected)</code> should return <code>true</code>.</li>
  </ol>
  
  <hr>
  
  <p>I'm having trouble when invoking a <code>new Action</code> to inject some javascript.</p>
  
  <p>The javascript function that tests if <code>TestUrl.Equals(expected)</code> <strong>should</strong> return <code>true</code>, but for some odd reason, when I step through my program, <strong>it seems to run everything twice</strong>... with the <code>if</code> statement first coming out as <code>false</code> and then as <code>true</code>.</p>
  
  <p>I think this is a threading/code flow issue but I'm not sure where.  I was thinking to put all the code that runs after the <code>Navigate()</code> function <strong>inside of</strong> the <code>WebBrowserDocumentCompleted</code> function, but I can't figure out how to pass any of my variables inside that function, so I'm not sure how that'd work.</p>
  
  <pre><code>    public void GetScenarios()
      {
          new Thread(() =&gt;
          {
              using (SqlConnection conn = new SqlConnection(connectionString))
              {
                  conn.Open();
                  using (SqlCommand cmd = new SqlCommand("SELECT * FROM Scenarios WHERE IsEnabled='1'", conn))
                  {
                      SqlDataReader reader = cmd.ExecuteReader();
                      if (reader.HasRows)
                      {
                          AutoResetEvent signal = new AutoResetEvent(false);
                          while (reader.Read())
                          {
                              /* Perform a test on the selected scenario
                               * (can do different types of tests)                              
                               * */
                              TestScenarios(reader, cmd, signal, Url, HasSucceeded);
                          }
                          reader.Close();
                      }
                  }
              }
          }).Start();
      }
  
      /// &lt;summary&gt;
      /// Waits for WebBrowser to complete loading the page
      /// &lt;/summary&gt;
      private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
      {
          ((AutoResetEvent)((WebBrowser)sender).Tag).Set();
      }
  
      /// &lt;summary&gt;
      /// Goes to specified Url
      /// Performs a test on the selected scenario
      /// &lt;/summary&gt;
      public int TestScenarios(SqlDataReader reader, SqlCommand cmd, AutoResetEvent signal, string Url, int HasSucceeded)
      {
          // Read XML
          string testType = "";
          string testElement = "";
          string expected = "";
  
          SqlXml sqlXml = reader.GetSqlXml(1);
          using (var xmlreader = sqlXml.CreateReader())
          {
              // Read XML values
          }
  
          // Navigate to Url
          Action action = () =&gt;
          {
              webBrowser2.Tag = signal;
              webBrowser2.Navigate(Url);
              webBrowser2.DocumentCompleted -= WebBrowserDocumentCompleted;
              webBrowser2.DocumentCompleted += WebBrowserDocumentCompleted;
          };
          webBrowser2.Invoke(action);
          signal.WaitOne();
  
  
          // If/else to determine type of test and run test
          if (testType == "Click")
          {
              webBrowser2.Invoke(new Action(() =&gt;
              {
                  HtmlElement head = webBrowser2.Document.GetElementsByTagName("head")[0];
                  HtmlElement testScript = webBrowser2.Document.CreateElement("script");
                  IHTMLScriptElement element = (IHTMLScriptElement)testScript.DomElement;
                  element.text = "function TestClick() { $('" + testElement + "')[0].click(); }";
                  head.AppendChild(testScript);
                  webBrowser2.Document.InvokeScript("TestClick");
  
                  string TestUrl = webBrowser2.Url.AbsoluteUri;
                  if (TestUrl.Equals(expected))
                  {
                      HasSucceeded = 1;
                  }
                  else
                  {
                      // No test
                  }
              }));
          }
          return HasSucceeded;
      }
  </code></pre>