![](/img/trans.png)
[英]How can I decouple this C# worker thread code from the main thread for shared data variables?
[英]How can i set variables in the main thread from another thread in C#?
我正在嘗試編寫一個C#函數來計算使用http請求的網頁上的損壞鏈接。 由於我想快速執行此操作,因此我為每個請求創建一個線程,然后簡單地增加線程中的計數器。 我的問題是,盡管我知道網站上有幾個斷開的鏈接,但計數器最后仍保持為0。 好像線程沒有在主線程中設置變量。
public volatile int found;
public volatile int notfound;
public void GetBrokenLinks(WebBrowser website)
{
HtmlElementCollection links = website.Document.GetElementsByTagName("a");
foreach (HtmlElement element in links)
{
string link = element.GetAttribute("href").ToString();
Uri urlCheck = new Uri(link);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlCheck);
request.Timeout = 10000;
try
{
Thread link_checher_thread = new Thread(delegate ()
{
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
response.Dispose();
found++;
}
else if (response.StatusCode == HttpStatusCode.NotFound)
{
response.Dispose();
notfound++;
}
});
link_checher_thread.IsBackground = true;
link_checher_thread.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
MessageBox.Show(found.ToString() + ", " + notfound.ToString());
}
我已經在互聯網上搜索了幾個小時,嘗試了volatile變量,但似乎沒有任何效果。 我如何強制線程在主線程中設置變量?
計數器不保持為0-問題更深,更容易。
Bes的事情:使用Interlocked類方法來增加和讀取類。 成品。 它們使用原子API,並且專為多線程操作而設計。
在.NET中增加共享計數器的正確方法是通過System.Threading.Interlocked.Increment(ref found)
您的代碼中有兩個主要問題:
您可以使用.Net框架中的Task輕松完成此任務。
public int found;
public int notfound;
public void GetBrokenLinks(WebBrowser website)
{
HtmlElementCollection links = website.Document.GetElementsByTagName("a");
List<Task> tasks = new List<Task>();
foreach (string element in links)
{
string link = element.GetAttribute("href").ToString();
tasks.Add(Task.Factory.StartNew(() =>
{
Uri urlCheck = new Uri(link);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlCheck);
request.Timeout = 10000;
HttpWebResponse response;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
response.Dispose();
Interlocked.Increment(ref found);
}
else if (response.StatusCode == HttpStatusCode.NotFound)
{
response.Dispose();
Interlocked.Increment(ref notfound);
}
}
));
}
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException ae)
{
ae.Handle((e) => { MessageBox.Show(e.ToString()); return true; });
}
MessageBox.Show(found.ToString() + ", " + notfound.ToString());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.