0

ここにはたくさんのコードがあるので、それが何をすべきかを簡単に説明しましょ

予想される流れ:

  1. GetScenarios();SQL 接続を開き、whileループを開始してScenariosデータベースをループします。
  2. データベース内の最初のアイテムが選択されたら、それに対して実行TestScenarios()します。
  3. TestScenarios()はアイテムの XML 値の一部を読み取り、そのうちの 1 つが であり、コントロールでUrlを開きます。UrlWebBrowser
  4. clickその Web ページが開かれると、ページ上の要素を (テスト) するために、一部の Javascript が挿入されて呼び出されます。
  5. if ステートメントTestUrl.Equals(expected)は を返しtrueます。

new Actionjavascript を挿入するために a を呼び出すときに問題が発生します。

を返すTestUrl.Equals(expected) 必要があるかどうかをテストする JavaScript 関数ですtrueが、何らかの奇妙な理由で、プログラムをステップ実行すると、すべてが 2 回実行されているようにif見えfalseますtrue

これはスレッド/コード フローの問題だと思いますが、どこにあるのかわかりません。関数の後に実行されるすべてのコードをNavigate()関数内に配置することを考えていましたが、その関数内で変数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;
    }
4

1 に答える 1

0

まず、Thread の代わりに Task または Task TResult を使用することをお勧めします。タスク内でアクションを実行し、完了まで待って結果を返すことができます

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;
于 2013-07-29T22:04:51.950 に答える