我正试图绕过线程,在我当前的应用程序中,线程将是处理它的最佳方式,我有:
public void threadsTest() {
Invoke(new MethodInvoker(() => {
// loop over the listview getting the first value
foreach (ListViewItem item in listViewBacklinks.Items)
{
// try...
try
{
var mainURL = item.Text;
using (WebClient wc = new WebClient())
{
try
{
var pageHtml = wc.DownloadString(mainURL);
if (pageHtml.Contains(Text))
{
var subitems = item.SubItems.Add("<a href=\"" + item.SubItems[1].Text + "\">anchor text</a>");
item.BackColor = Color.Green;
}
else
{
item.BackColor = Color.Red;
}
} catch (Exception)
{
item.BackColor = Color.Red;
}
//Helpers.returnMessage("Work done!");
}
} catch (Exception ex) {
Helpers.returnMessage(ex.ToString());
}
}}));
}
private void btnAnalyzeAnchorText_Click(object sender, EventArgs e)
{
// attempting threads
var t = new Thread(threadsTest);
t.Start();
}
我认为像backgroundWorker一样,它不会冻结GUI但它确实如此我放入调用来访问GUI元素,我不认为它看起来正确,现在的方式是GUI仍然没有响应,直到工作已经完成,我已经查看了一些教程,但它并没有完全沉入,任何关于破解线程的帮助/技巧都会很棒。
答案 0 :(得分:0)
这是你需要做的:
public void threadsTest(string[] urls)
{
var results = new Dictionary<string, string>();
foreach (string mainURL in urls)
{
using (WebClient wc = new WebClient())
{
var pageHtml = wc.DownloadString(mainURL);
results[mainUrl] = pageHtml;
}
}
Invoke(new MethodInvoker(() => ProcessResults(results)));
}
此代码中没有UI元素,只是WebClient
的重要内容。
然后在新的ProcessResults
中,您回到UI线程,然后就可以设置结果。
对线程的调用需要通过一个url(字符串)数组,但是你在创建线程之前就已经知道了,所以你仍然在UI线程中,这样做是安全的。