c#中的webbrowser 多線程 【轉載】

來源:互聯網
上載者:User

我們在做採集軟體的時候

有些網站通過直接分析html文本是很麻煩的事情

在利用WinForm編程的情況下

有一種更好的方式當然是分析HtmlDocument

然而,這HtmlDoucment並不能直接建立

它必須由 WebBroswer控制項Navigate產生一個頁面後

才能取得wb.HtmlDocument

然後就可以對HtmlDocument的各元素、標籤進行分析。

 

事實上,在採集的時候

並不是採集只會採集單個頁面

這樣的話,在主表單中就可以完成

 

譬如採集一些列表頁面,有N多個頁

那麼,一個迴圈下去,

用WebBrowser去響應,那就會導致假死

這時候,我們肯定會想到用多線程去做這件事情

 

C#的多線程,

大家應該都知道,有STA,MTA兩種模式

然而,WebBrowser控制項卻有一個不好的特點

那就是:它只支援多線程STA模式

例如下面的代碼,

Thread tread = new Thread(new ParameterizedThreadStart(BeginCatch));
tread.SetApartmentState(ApartmentState.STA);
tread.Start(url);

 

 

 private void BeginCatch(object obj)
{
     string url = obj.ToString();
     WebBrowser wb = new WebBrowser();
     wb.ScriptErrorsSuppressed = true;
     wb.Navigate(url);
     wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);

 

需要分析WebBrowser產生 的HtmlDocument時,必須在事件DocumentCompleted裡面去操作

只有這時候,WebBrowser才算載入完成

 

不過,這隻是一個陷阱!!!!

WebBrowser有一個特性,那就是在多線程STA的時候,根本就不等到DocumentCompleted的執行

也就是無法再進行後面的操作!!!

 

這樣的話,我們該如何辦呢?

也許有人會想:wb.Document.Write(string)方法,如下:

 

 

private void BeginCatch(object obj)
{
     string url = obj.ToString();
     WebBrowser wb = new WebBrowser();
     wb.ScriptErrorsSuppressed = true;

     string htmlcode = GetHtmlSource(url); 
     wb.Document.Write(htmlcode);
     //執行分析操作    

//WebClient取網頁源碼
private string GetHtmlSource(string Url)
{
     string text1 = "";
     try
     {
        System.Net.WebClient wc = new WebClient();
        text1 = wc.DownloadString(Url);
     }
     catch (Exception exception1)
     {}
     return text1;
}

 

 

但這時候,我們會發現,wb.DocumentText總是沒有的

當時我也很鬱悶,搜尋園子裡的文章與MSDN,都是可以用DocumentText賦值的

但也在網上發現了很多說操作後沒有結果的

 

經過努力搜尋

在園子裡發現了一篇有用的文章裡提到的一個例子

經過測試後發現

WebBrowser必須經過Navigate後才會產生Document

於是忽,終於可以實現了多線程下面的操作了

最終代碼如下

 

private void ThreadWebBrowser(string url)
{
   Thread tread = new Thread(new ParameterizedThreadStart(BeginCatch));
   tread.SetApartmentState(ApartmentState.STA);
   tread.Start(url);
}

private void BeginCatch(object obj)
{
     string url = obj.ToString();
     WebBrowser wb = new WebBrowser();
     wb.ScriptErrorsSuppressed = true;
     //在這裡Navigate一個空白頁面
     wb.Navigate("about:blank");
     string htmlcode = GetHtmlSource(url); 
     wb.Document.Write(htmlcode);
     //執行分析操作   ……(略) 

//WebClient取網頁源碼
private string GetHtmlSource(string Url)
{
     string text1 = "";
     try
     {
        System.Net.WebClient wc = new WebClient();
        text1 = wc.DownloadString(Url);
     }
     catch (Exception exception1)
     {}
     return text1;
}

 

 

當然,線上程裡面處理每個結點與資料庫操作的時候,可以用ThreadPool

這樣效果與效能可能好一些

 

希望此文對有大家有所協助~:)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.