C# 开始使用线程
我正试图了解线程,在我当前的应用程序中,线程是处理它的最佳方式,我所拥有的:C# 开始使用线程,c#,C#,我正试图了解线程,在我当前的应用程序中,线程是处理它的最佳方式,我所拥有的: public void threadsTest() { Invoke(new MethodInvoker(() => { // loop over the listview getting the first value foreach (ListViewItem item in listViewBacklinks.Items) {
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();
}
public void threadsTest(){
调用(新方法调用程序(()=>{
//在listview上循环以获取第一个值
foreach(listViewBacklinks.Items中的ListViewItem项)
{
//试试看。。。
尝试
{
var mainURL=item.Text;
使用(WebClient wc=new WebClient())
{
尝试
{
var pageHtml=wc.DownloadString(mainURL);
如果(页面html.Contains(文本))
{
var subitems=item.subitems.Add(“”);
item.BackColor=Color.Green;
}
其他的
{
item.BackColor=Color.Red;
}
}捕获(例外)
{
item.BackColor=Color.Red;
}
//Helpers.returnMessage(“工作完成!”);
}
}捕获(例外情况除外){
returnMessage(例如ToString());
}
}}));
}
私有void btnAnalyzeAnchorText_单击(对象发送者,事件参数e)
{
//正在尝试线程
var t=新螺纹(螺纹试验);
t、 Start();
}
我想就像backgroundWorker一样,它不会冻结GUI,但它确实冻结了GUI,所以我加入了调用来访问GUI元素,我认为它看起来不正确,现在的GUI在工作完成之前仍然没有响应,我看过一些教程,但它并没有完全沉入其中,任何关于破解线程的帮助/提示都将非常有用。这是您需要做的:
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)));
}
public void threadsTest(字符串[]URL)
{
var results=newdictionary();
foreach(URL中的字符串mainURL)
{
使用(WebClient wc=new WebClient())
{
var pageHtml=wc.DownloadString(mainURL);
结果[mainUrl]=pageHtml;
}
}
调用(newmethodinvoker(()=>ProcessResults(results));
}
此代码中没有UI元素,只有WebClient
的繁重工作
然后在新的ProcessResults
中,您回到UI线程,这样您就可以设置结果了
对线程的调用需要通过一个URL(字符串)数组,但在创建线程之前就得到了这个URL(字符串),因此您仍然在UI线程中,这样做是安全的。
Invoke()
在UI线程上运行给定的代码,因此您的UI被阻塞也就不足为奇了。调用/开始仅调用您可以调用的代码的最小部分(即在此处设置背景色)。如果您的列表太大,您仍然可能会在过于频繁地更新UI时遇到问题。我建议研究async/await,因为这将是一种更优雅的方式来完成您正在尝试的操作。WebClient的可能副本是GUI元素,因此您的应用程序根本不适合线程处理……一旦删除调用,我确实会遇到跨线程错误,如何在不调用的情况下获取GUI值?谢谢你的帮助。您最好对代码进行结构化,这样就不会将UI交互与使用WebClient获取数据的业务混为一谈。最好不要考虑线程,而是考虑异步IO(使用async/await)。