2010-10-10 105 views
1

我是線程新手。我正嘗試使用多線程發送HTTP Web請求,但我無法達到我需要的效果。 我的要求是發送請求到數千個相同或不同的網站,並解析我從httpwebrequest得到的響應。 在下面的代碼中,我發送2個simulteaneous線程,我正在尋找10個同時線程。C#HTTPWebRequest多線程

namespace threading 
{ 
public partial class Form1 : Form 
{ 
    delegate string UrlFetcher(string url); 

    private void button1_Click(object sender, EventArgs e) 
    { 
     int i = 1; 
     UrlFetcher u = new UrlFetcher(Fetch); 
     UrlFetcher u = new UrlFetcher(Fetch1); 
     string pageURL = "http://www.google.com"; 

     while (i <= 1000) 
     { 
      u.BeginInvoke(pageURL, new AsyncCallback(AfterFetch), "this is state"); 
      i++; 
      u.BeginInvoke(pageURL, new AsyncCallback(AfterFetch1), "this is state"); 
      i++; 
      Thread.Sleep(5); 
     } 
    } 

    static string Fetch(string pageURL) 
    { 
     HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(pageURL); 
     WebReq.Method = "GET"; 
     HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse(); 
     Stream Answer = WebResp.GetResponseStream(); 
     StreamReader _Answer = new StreamReader(Answer); 
     string myString = _Answer.ReadToEnd(); 
     return myString; 
    } 

    void AfterFetch(IAsyncResult result) 
    { 
     string a; 

     AsyncResult async = (AsyncResult)result; 
     UrlFetcher fetcher = (UrlFetcher)async.AsyncDelegate; 
     a = fetcher.EndInvoke(result).ToString(); 

     Regex regx = new Regex(@"<td>([A-Za-z0-9\-]+)\.(com|net)</td>", RegexOptions.IgnoreCase); 
     MatchCollection mactches = regx.Matches(a); 
     foreach (Match match in mactches) 
     { 
      string pattern = @"<(.|\n)*?>"; 
      string r = Regex.Replace(match.Value, pattern, string.Empty); 
      textBox3.AppendText(r); 
     } 
    } 

    static string Fetch1(string pageURL) 
    { 
     HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create(pageURL); 
     WebReq.Method = "GET"; 
     HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse(); 
     Stream Answer = WebResp.GetResponseStream(); 
     StreamReader _Answer = new StreamReader(Answer); 
     string myString = _Answer.ReadToEnd(); 
     return myString; 
    } 

    void AfterFetch1(IAsyncResult result) 
    { 
     string a; 

     AsyncResult async = (AsyncResult)result; 
     UrlFetcher fetcher = (UrlFetcher)async.AsyncDelegate; 
     a = fetcher.EndInvoke(result).ToString(); 

     Regex regx = new Regex(@"<td>([A-Za-z0-9\-]+)\.(com|net)</td>", RegexOptions.IgnoreCase); 
     MatchCollection mactches = regx.Matches(a); 
     foreach (Match match in mactches) 
     { 
      string pattern = @"<(.|\n)*?>"; 
      string r = Regex.Replace(match.Value, pattern, string.Empty); 
      textBox3.AppendText(r); 
     } 
    } 
} 
} 

如果有人會糾正上面的代碼,它真的很感激。

感謝

回答

5

我想說

  • 廢除您的代理
  • 設置一個WebRequest的循環中
  • 使用得到響應的異步版本(Begin/End)GetResponse
  • 讓你異步回調可重入(獨立於任何實例狀態),並使用「結束」調用的結果以及您傳入的任何狀態(例如WebRequest itse LF)

應該或多或少工作

+0

+1 - 需要做什麼。異步委託方法幾乎沒有幫助代碼執行,因爲每個請求仍然會阻塞一個線程,而如果使用WebRequest/WebResponse/Stream/...上的異步操作,情況並非如此。 – Lucero 2010-10-10 13:03:20

+1

因爲我是線程新手,有人可以在適當的位置使用end response來糾正上面的代碼。 – user471524 2010-10-10 13:27:10

+1

另外,處置WebResponse和Stream(從GetResponseStream返回),以便您不再使用的連接正確關閉。 – 2010-10-10 20:42:27