2012-08-13 174 views
0

我對Seaprate線程做多HttpWebRequests阻塞UI線程,但我的UI線程被阻塞,幾乎所有的時間我打電話Start()後,我想不通爲什麼,這裏是最重要的代碼:HttpWebRequests從另一個線程

private void Start() 
{ 
    for (int i = 0; i < 10; i++) 
    { 
     var todo = UrlStack.UrlPartitions.First(); 
     UrlStack.UrlPartitions.Remove(todo); 
     ThreadPool.QueueUserWorkItem(new WaitCallback(ScanSites), todo); 
    } 
} 
private void ScanSites(object o) 
{ 
    var ToDo = (List<string>)o; 
    foreach (string Url in ToDo) 
    { 
     var state = MakeRequest(Url); 
     var website = WebsiteProcessing.ProcessResponse(state); 
     if (website != null) 
     { 
      Websites.Add(website); 
      WebsitesCount++; 
      this.UIThread(() => lblCrawledWebsites.Text = WebsitesCount.ToString()); 
     } 
    } 
} 
private static RequestState MakeRequest(string url) 
{ 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 
    ... 
    RequestState state = new RequestState(); 
    HttpWebResponse response = null; 
    Stream responseStream = null; 
    StreamReader sr = null; 

    try 
    { 
     response = (HttpWebResponse)request.GetResponse(); 
     responseStream = response.GetResponseStream(); 
     sr = new StreamReader(responseStream); 
     state.Request = (HttpWebRequest)request; 
     state.Response = (HttpWebResponse)response; 
     string strContent = sr.ReadToEnd(); 
     state.ResponseContent = new StringBuilder(strContent); 
    } 
    catch 
    { 
     return null; 
    } 

    finally 
    { 
     if (responseStream != null) 
      responseStream.Close(); 
     if (sr != null) 
      sr.Close(); 
     if (response != null) 
      response.Close(); 
    } 

    return state; 
} 
+0

this.UIThread(...)的實現是什麼?您正在UI線程中更新控件,因此ToDo有多大?如果它包含很多行,這意味着很多更新,這意味着一個緩慢的用戶界面。在完成之前,您是否需要更新UI? – Maarten 2012-08-13 06:03:57

+0

@Maarten UIThread檢查是否需要調用,如果調用需要調用。 ToDo Size依賴於var,但即使有100行的線程仍然會阻塞,即使我刪除了更新UI,窗口仍然無響應的行,也無法移動它等等。 – formatc 2012-08-13 09:54:28

+0

聽起來像是某種競爭條件。您只顯示了部分代碼,因此很難在上面的代碼中找到它。 – Maarten 2012-08-13 10:22:50

回答

0

我發現了讓我非常驚訝的故障。這是一個20-30個正則表達式的自定義類,用於在用HtmlAgilityPack拉動文本後剝離剩餘的HTML,但我仍不明白的是後臺線程如何阻止UI,CPU峯值永遠不會超過50%。

0

可能是因爲這個電話?

this.UIThread(() => lblCrawledWebsites.Text = WebsitesCount.ToString()); 

您沒有提供UIThread的定義,但看起來像是對UI線程的編組調用。在這種情況下,如果ToDo列表中有許多URL,則可能會阻塞UI線程。