【问题标题】:Managing multiple threads and general code flow管理多线程和一般代码流
【发布时间】:2013-07-29 21:13:38
【问题描述】:

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

预期流量:

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

我在调用 new Action 注入一些 javascript 时遇到问题。

测试TestUrl.Equals(expected)是否应该返回true的javascript函数,但出于某种奇怪的原因,当我单步执行我的程序时,它似乎运行了两次... if 语句首先以false 出现,然后以true 出现。

我认为这是一个线程/代码流问题,但我不确定在哪里。我正在考虑将所有在Navigate() 函数inside of 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;
    }

【问题讨论】:

  • 我的猜测是返回 HasSucceeded 已经完成,之后该操作已被调用。

标签: c# multithreading while-loop


【解决方案1】:

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

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多