1.分析和下載不能同步進行。在《爬蟲/蜘蛛程序的制作(C#語言)》中已經介紹了爬蟲程序的兩個步驟:分析和下載。在單線程的程序中,兩者是無法同時進行的。也就是說,分析時會造成網絡空閒,分析的時間越長,下載的效率越低。反之也是一樣,下載時無法同時進行分析,只有停下下載後才能進行下一步的分析。問題浮出水面,我想大家都會想到:把分析和下載用不同的線程進行,問題不就解決了嗎?
2.只是單線程下載。相信大家都有用過網際快車等下載資源的經歷,它裡面是可以設置線程數的(近年版本默認是10,曾經默認是5)。它會將文件分成與線程數相同的部分,然後每個線程下載自己的那一部分,這樣下載效率就有可能提高。相信大家都有加多線程數,提升下載效率的經歷。但細心的用戶會發現,在帶寬一定的情況下,並不是線程越多,速度越快,而是在某一點達到峰值。爬蟲作為特殊的下載工具,不具備多線程的能力何以有效率可談?爬蟲在信息時代的目的,難道不是快速獲取信息嗎?所以,爬蟲需要有多線程(可控數量)同時下載網頁。
好了,認識、分析完問題,就是解決問題了:
多線程在C#中並不難實現。它有一個命名空間:System.Threading,提供了多線程的支持。
要開啟一個新線程,需要以下的初始化:
ThreadStart startDownload = new ThreadStart( DownLoad );
//線程起始設置:即每個線程都執行DownLoad(),注意:DownLoad()必須為不帶有參數的方法
Thread downloadThread = new Thread( startDownload ); //實例化要開啟的新類
downloadThread.Start();//開啟線程
由於線程起始時啟動的方法不能帶有參數,這就為多線程共享資源添加了麻煩。不過我們可以用類級變量(當然也可以使用其它方法,筆者認為此方法最簡單易用)來解決這個問題。知道開啟多線程下載的方法後,大家可能會產生幾個疑問:
1.如何控制線程的數量?
2.如何防止多線程下載同一網頁?
3.如何判斷線程結束?
4.如何控制線程結束?
下面就這幾個問題提出解決方法:
1.線程數量我們可以通過for循環來實現,就如同當年初學編程的打點程序一樣。
比如已知用戶指定了n(它是一個int型變量)個線程吧,可以用如下方法開啟五個線程。
Thread[] downloadThread;
//聲名下載線程,這是C#的優勢,即數組初始化時,不需要指定其長度,可以在使用時才指定。
這個聲名應為類級,這樣也就為其它方法控件它們提供了可能
ThreadStart startDownload = new ThreadStart( DownLoad );
//線程起始設置:即每個線程都執行DownLoad()
downloadThread = new Thread[ n ];//為線程申請資源,確定線程總數
for( int i = 0; i < n; i++ )//開啟指定數量的線程數
{
downloadThread[i] = new Thread( startDownload );//指定線程起始設置
downloadThread[i].Start();//逐個開啟線程
}
好了,實現控制開啟線程數是不是很簡單啊?