之前做的采集程序, 是單線程的, 一個圖片列表, 要等着一一采完....浪費了不少時間, 正好今天家里帶寬升級, 可以使用多線程采集了.... 連夜改進原來的程序. 使用多線程去采集....
設定思路: 采集目標: http://www.8kmm.com, 已知網址列表(List保存), 應用多線程(Thread)讀取該列表, 獲取url時不能重復(加鎖Lock). 允許無序采集!

先放個美女提提神!
多線程核心代碼:
1 #region 全局變量 2 //線程列表 3 List<Thread> threadslList = new List<Thread>(); 4 //Url列表 5 List<string> uUrls = new List<string>(); 6 //處理完畢的列表 7 List<string> OkUrls = new List<string>(); 8 //成功取得的美女圖片數量 9 public int ImgCount = 0; 10 #endregion 11 12 13 //取圖開始 按鈕事件 14 private void lbtnGetWebImgStart_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 15 { 16 lbtnGetWebImgStart.Enabled = false; 17 GetWebSiteImg(); 18 } 19 20 //取圖停止 按鈕事件 21 private void lbtnGetWebImgStop_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 22 { 23 try 24 { 25 foreach (Thread t in threadslList) 26 { 27 if (t != null) 28 { 29 t.Abort(); 30 } 31 } 32 } 33 catch (Exception ex) 34 { 35 WriteLog("停止失敗:" + ex.Message); 36 } 37 finally 38 { 39 lbtnGetWebImgStart.Enabled = true; 40 } 41 } 42 43 /// <summary> 44 /// 獲取圖片主方法 45 /// </summary> 46 private void GetWebSiteImg() 47 { 48 try 49 { 50 ImgCount = 0; 51 OkUrls.Clear(); 52 uUrls.Clear(); 53 threadslList.Clear(); //先初始化以上 54 string[] urls = txtUrl.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 55 lblC.Text = urls.Length.ToString(CultureInfo.InvariantCulture); 56 uUrls = new List<string>(urls); 57 for (int i = 0; i < int.Parse(numThreadUD.Text); i++) // 循環創建線程 58 { 59 Thread t = new Thread(Task); 60 t.Name = i.ToString(); 61 t.IsBackground = true; 62 threadslList.Add(t); 63 t.Start(); 64 } 65 } 66 catch (Exception ex) 67 { 68 WriteLog(ex.Message); 69 } 70 } 71 72 73 public void Task() 74 { 75 while (uUrls.Count > 0) 76 { 77 lblMsg.Text = string.Format("剩余:{0},已訪問:{1},當前線程數:{2}", uUrls.Count, (OkUrls.Count + 1), threadslList.Count); 78 string url = GetUrl(); 79 if (url == "") 80 { 81 break; 82 } 83 else 84 { 85 if (GetHttpImg(url) == 200)//只有狀態200才是正常的, GetHttpImg是我封裝的方法, 獲取網頁, 正則取得所有合規范的圖片. 86 { 87 OkUrls.Add(url); 88 lblInfoStart.Text = (int.Parse(lblInfoStart.Text) + 1).ToString(CultureInfo.InvariantCulture); 89 WriteHtml(txtUrl.Text); 90 if (lblC.Text == lblInfoStart.Text)//判斷當前數量是否已是總數. 91 { 92 lblMsg.Text = "完成"; 93 } 94 } 95 } 96 } 97 } 98 99 100 /// <summary> 101 /// 線程加鎖,防止多個線程同時從list里面取出第一個 102 /// </summary> 103 /// <returns></returns> 104 public string GetUrl() 105 { 106 lock ("GetUrl") 107 { 108 if (uUrls.Count > 0) 109 { 110 string url = uUrls[0]; 111 uUrls.RemoveAt(0); 112 return url; 113 } 114 else 115 { 116 return ""; 117 } 118 } 119 }
代碼超級簡單, 測試抓取幾個列表, 沒有問題, 等會用它去抓更多MM。。。
