管理多个线程和一般代码流

时间:2013-07-29 21:53:59

标签: c# multithreading while-loop

这里有很多代码,所以让我快速解释应该做什么。

预期流程:

  1. GetScenarios();打开SQL连接并启动while循环以循环遍历Scenarios数据库。
  2. 选择数据库中的第一项后,在其上运行TestScenarios()
  3. TestScenarios()读取项目的某些XML值,其中一个是Url,然后在Url控件中打开WebBrowser
  4. 当该网页打开时,会注入并调用一些Javascript,以便click(测试)页面上的元素。
  5. if语句TestUrl.Equals(expected)应返回true

  6. 我在调用new Action注入一些javascript时遇到了麻烦。

    测试TestUrl.Equals(expected) 应该返回true的javascript函数,但由于某些奇怪的原因,当我单步执行我的程序时,似乎运行了所有内容两次 ... if语句首先显示为false,然后显示为true

    我认为这是一个线程/代码流问题,但我不知道在哪里。我正在考虑将Navigate()函数之后的所有代码放在<{strong> WebBrowserDocumentCompleted函数中,但我无法弄清楚如何将任何变量传递到里面那个功能,所以我不确定它是如何工作的。

        public void GetScenarios()
        {
            new Thread(() =>
            {
                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();
        }
    
        /// <summary>
        /// Waits for WebBrowser to complete loading the page
        /// </summary>
        private void WebBrowserDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs Url)
        {
            ((AutoResetEvent)((WebBrowser)sender).Tag).Set();
        }
    
        /// <summary>
        /// Goes to specified Url
        /// Performs a test on the selected scenario
        /// </summary>
        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 = () =>
            {
                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(() =>
                {
                    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;
        }
    

1 个答案:

答案 0 :(得分:0)

首先,最好使用Task或Task TResult而不是Thread。您可以在任务中执行操作并等待完成并返回结果

Func<bool> action = () =>
        {
            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;
        };

        Task<bool> task = new Task<bool>(action);
        task.Start();
        task.Wait();
        return task.Result;