2012-05-01 29 views
0

我有很多網址(約800)從網上下載。我有一個類:HttpDownloader.cs與HttpWebRequest類一起使用來下載並獲取html頁面。之後,我通過正則表達式來對頁面進行解析。通過BackgroundWorker組件從網上下載很多頁面

我想使用BackgroundWorker組件,但是我不知道該怎麼做全部是的頁面。通過一個循環,或類似的東西。

我的代碼:

我試着使用線程池用,它真的沒有問題。我嘗試了4個網址,並沒有奏效。

 foreach (string link in MyListOfUrls) 
     { 
ThreadPool.QueueUserWorkItem((o) => { 

      HttpDownloader httpDownload = new HttpDownloader(link); 
      string htmlDoc = httpDownload.GetPage();//get the html of the page 
      HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
      DoPharsing();//my func for pharsing 
      Save();//save into dataBase 
    }); 
     } 

因爲我在我的FUNC連接到數據庫和數據表使用我得到一個異常,當我使用線程池:

「禁用的,因爲以前的功能評價 超時功能評價你必須繼續執行到重新啓用功能 評估。「

所以,我無法從DataTable中獲取數據。也許我需要下載所有,然後做pharsing和保存??

如何將其更改爲BackgroundWorker組件的異步?

p.s.不要使用Async Tpc建議我,因爲我沒有設法下載它。

感謝

+0

是否要同時執行多個下載,或者簡單地從GUI下載(使其異步)? (順便說一句,它的解析,而不是phanal) – digEmAll

+0

@digEmAll,我想同時執行多個下載。要更加快速地下載**全部**頁面。 –

+0

你有什麼嘗試?互聯網上有許多關於後臺工人類的教程。你用這些教程得到了多少東西,你有什麼特別的困擾?請發佈您的代碼嘗試使用BackgroundWorker。 –

回答

0

我終於找到我的答案
這裏是我的代碼:

static BackgroundWorker[] d=new BackgroundWorker[MyListOfUrls.Length]; 
    string html=new string[MyListOfUrls.Length] 

    static void Main(string[] args) 
    { 
    for (int i = 0; i < MyListOfUrls.Length; i++) 
    { 
     d[i]=new BackgroundWorker{WorkerReportsProgress=true}; 
     d[i].DoWork += new DoWorkEventHandler(worker2_DoWork); 
     d[i].ProgressChanged += new ProgressChangedEventHandler(Program_ProgressChanged); 
     d[i].RunWorkerAsync(i); 
     d[i].RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted); 
     Thread.Sleep(1000); 
    } 
    } 

    static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("End"); 
    } 

    static void Program_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     Console.WriteLine(e.ProgressPercentage.ToString()); 
    } 

    static void worker2_DoWork(object sender, DoWorkEventArgs e) 
    { 
     var worker = (BackgroundWorker)sender; 
     worker.ReportProgress((int)e.Argument); 

     HttpDownloader httpDownload = new HttpDownloader(link); 
     html[(int)e.Argument] = httpDownload.GetPage(); 

     Thread.Sleep(500); 
    } 

如果有人知道如何做的更好,我會很高興。 Thaks, Chani

1

這取決於你想拆斷,整個循環,或只是循環的下載部分內容。顯然,如果你想整個循環在後臺,那麼最簡單的方法就是使用ThreadPool。

請注意,您可能必須更改解析並保存函數,以便將HTML文檔傳遞給每個函數。

ThreadPool.QueueUserWorkItem((o) => { 
    foreach (string link in MyListOfUrls) 
    { 
    HttpDownloader httpDownload = new HttpDownloader(link); 
    string htmlDoc = httpDownload.GetPage();//get the html of the page 
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
    var result = DoPharsing(doc);//my func for pharsing 
    Save(result);//save into dataBase 
} 
}); 

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += (o, e) => { 
    foreach (string link in MyListOfUrls) 
    { 
    HttpDownloader httpDownload = new HttpDownloader(link); 
    string htmlDoc = httpDownload.GetPage();//get the html of the page 
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
    var result = DoPharsing(doc);//my func for pharsing 
    Save(result);//save into dataBase 
} 
}; 
worker.RunWorkerCompleted += (o, e) => { 
    // Job completed 
} 
worker.RunWorkerAsync(); 

要在同一時間下載多個環節簡單地切換出來,你所創建的線程:

foreach (string link in MyListOfUrls) 
{ 
    ThreadPool.QueueUserWorkItem((o) => { 
    HttpDownloader httpDownload = new HttpDownloader(link); 
    string htmlDoc = httpDownload.GetPage();//get the html of the page 
    HtmlDocument doc=doc.LoadHtml(htmlDoc);//load html string to doc for pharsing 
    var result = DoPharsing(doc);//my func for pharsing 
    Save(result);//save into dataBase 
    }); 
} 

(更好的用戶線程池,這裏比創造數百名後臺工作者,我認爲)。

+0

你也可以做'Parallel.ForEach'。這裏實現的問題是它不支持乾淨取消。您必須等到線程完成後乾淨地停止下載 - 無論是下載完成後還是連接超時。唯一的解決方法是使用非阻塞的下載機制,在這種情況下,您不必自行排隊線程。 –

+0

與上面2個例子有什麼不同?是否下載異步,如同時下載頁面? –

+0

@Chanipoz:這裏有三個例子。前兩個幾乎完全相同,並且只有幫助,因爲它們會讓GUI不能掛起。他們不會同時下載多個文檔。第三個可以同時下載多個文檔,但可以排隊很多線程池工作項目。我猜測,因爲它「排隊」,這不是一個問題,它會在內部只同時運行這麼多的任務。 –