管理多个线程和常规代码流
本文关键字:常规 代码 线程 管理 | 更新日期: 2023-09-27 18:25:29
这里有很多代码,所以让我快速解释一下它应该做什么。
预期流量:
-
GetScenarios();
打开 SQL 连接并启动while
循环以循环遍历Scenarios
数据库。 - 选择数据库中的第一项后,对其运行
TestScenarios()
。 -
TestScenarios()
读取项的某些 XML 值(其中一个值为Url
(,然后在WebBrowser
控件中打开Url
。 - 当该网页打开时,会注入并调用一些Javascript,以便在页面上
click
(测试(元素。 - if 语句
TestUrl.Equals(expected)
应返回true
。
我在调用new Action
注入一些 javascript 时遇到问题。
测试TestUrl.Equals(expected)
是否应该返回true
的 javascript 函数,但由于某种奇怪的原因,当我逐步完成我的程序时,它似乎运行了两次所有内容......随着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;
}
首先,最好使用 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;