2009-09-23 30 views
2

是否可以在BackgroundWorker的後臺線程中創建WebBrowser控件?在backgroundworker的後臺線程中創建webbrowser控件

Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    Using web1 As New WebBrowser 

    End Using 
End Sub 

這引發以下錯誤:

ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.

有誰知道一個方法來創建一個web瀏覽器的背景?我想這樣做是爲了從網站中提取信息,然後吐出各種HTML DOM陣列

回答

0

Webbrowser運行的線程必須是ApartmentState .STA。從BackgroundWorker線程中,您必須在UI對象上使用Invoke,並在該上下文中添加Webbrowser。

我不認爲你真的需要在後臺線程中運行WebBrowser對象。所有的功能都是與事件異步處理的。

+1

我不是試圖將一個網頁瀏覽器添加到窗體,但加載它作爲一個類,並使用它的DOM功能,從提取信息網站,最終目標是將htmldocument對象傳送到backgroundworker結果對象 – Jim

+0

OK。然後,而不是使用BackgroundWorker,創建一個真正的線程並使用.SetApartmentState(ApartmentState.STA)。這可能有效。 –

+0

我做了很多這樣的工作,並發現用這種方法試圖做大規模的任何事情都非常痛苦。 WB控制太脆弱了。當以這種方式自動化時,它崩潰,顯示模式對話框,返回空白頁面,以及其他許多問題。我去下載了原始的html並且用雄偉的解析它(http://www.majestic12.co.uk/projects/html_parser.php)。從長遠來看,這可能會快1000倍,更可靠。 –

0

您也可以編寫一個包裝類,它實例化Web瀏覽器控件,創建包裝提取函數的方法,並通過公共事件觸發結果。

從這裏您只需創建一個新的包裝實例,並將其添加到ThreadPool。

記得做正確的所有者線程調用,以避免交叉線異常;)

0

已下跌兩路,我會建議WatiN,開源庫自動化IE和Firefox。 WebBrowser控件適用於顯示內容,但對於任何更復雜的內容來說,這成爲一大麻煩。

+0

嗯不試圖顯示的內容只提取與jscript客戶端操縱完好的DOM元素,例如,如果jscript改變頁面加載圖像,我想要的結果HTML文檔和DOM結構,我可以在程序中操作,思考我可以使用網頁瀏覽器進行轉義。我並不期望被線程問題減慢 – Jim

+0

現在卡住了我該如何讓線程做一些有用的事情,因爲我現在不瞭解THREAD構造函數,也習慣於背景工作者 – Jim

1

設置你的線程的公寓狀態的線程開始之前:

myThread.IsBackground = false; 
myThread.SetApartmentState(ApartmentState.STA); 
myThread.Start(); 
相關問題