2008-12-15 60 views
0

我有一個WebBrowser控件,它正在從後臺STA線程動態地實例化,因爲父線程是一個BackgroundWorker並且有很多其他的事情要做。WebBrowser.Navigated僅當我MessageBox.Show();

問題是導航事件從不觸發,除非我在告訴它到.Navigate()的方法中彈出一個MessageBox.Show()。我將解釋:

ThreadStart ts = new ThreadStart(GetLandingPageContent_ChildThread); 
Thread t = new Thread(ts); 
t.SetApartmentState(ApartmentState.STA); 
t.Name = "Mailbox Processor"; 
t.Start(); 

protected void GetLandingPageContent_ChildThread() 
{ 
WebBrowser wb = new WebBrowser(); 
wb.Navigated += new WebBrowserNavigatedEventHandler(wb_Navigated); 
wb.Navigate(_url); 
MessageBox.Show("W00t"); 
} 

protected void wb_Navigated(object sender, WebBrowserNavigatedEventArgs e) 
{ 
WebBrowser wb = (WebBrowser)sender; // Breakpoint 
HtmlDocument hDoc = wb.Document; 
} 

這工作正常;但是由於這是一個自動化應用程序,所以messagebox將會阻止。當我刪除MessageBox.Show()時,WebBrowser.Navigated事件從不觸發。我試着用Thread.Sleep()取代這一行,並暫停父線程。我打算在WebBrowser完成它的工作時掛起父線程,並找到一些方法將生成的HTML傳遞迴父線程,以便繼續執行更多邏輯。

它爲什麼這樣做?我該如何解決它?

如果有人可以爲我提供一種獲取網頁內容的方法,請填寫一些數據,然後在提交按鈕的另一端返回頁面內容, t支持POST動詞,也不通過QueryString傳遞數據,我也會接受這個答案,因爲整個練習都是不必要的。


解決方案:我最終只是沒有使用BackgroundWorker和從屬線程都在團隊建築師的建議...雖然在響應:(

回答

2

WebBrowser的費用不會做很多,除非它顯示,並有一個UI線程關聯;您是否顯示它所在的表單?您需要,使用DOM等。如果您不想將它顯示到屏幕上用戶,但它不會在服務中運行良好(例如)。

For scraping purpo ses,你通常可以使用WebClient等模擬一個普通的HTML browwser等等。這是不夠的?您可以使用諸如「Fiddler」之類的工具來調查您需要對服務器進行的確切請求。除此之外,您可以查看HTML Agility Pack,它提供了在沒有瀏覽器的情況下對HTML的DOM訪問。

+0

否; WebClient和HTTP POST方法都會失敗,因爲服務器不會' t HTTP 405支持是方法。給定有效載荷時,WebClient也不能通過GET工作。 – tsilb 2008-12-15 20:39:24

+0

那麼,網絡瀏覽器必須以某種方式發送*。通過fiddler查看實際的http請求,並以此爲起點。 – 2008-12-15 20:42:37

+0

Marc - 我認爲這是一個事件問題,而請求的內容並不真正相關。 – TheSoftwareJedi 2008-12-15 20:43:37

0

是否有GUI線程已啓動?也許WebBrowser對象使用GUI線程來處理事件。在這種情況下,您應該從創建WebBrowser的線程調用Application.Run()(用此替換您的MessageBox.Show())。 Application.Run()將掛起,直到調用Application.Exit()。

試圖現在測試這個。

1

如果WebBrowser的可見性設置爲false,則不會觸發Navigated和DocumentComplete事件。您可以解決此限制通過使WebBrowser控件可見,但其設置的位置,使得它像用戶界面之外:

wb.Visible = true; 
wb.Left = -wb.Width; // notice the minus sign 
0

最後我只是沒有使用BackgroundWorker和從屬線程都在的建議團隊建築師......雖然在響應:(

1

的費用,你需要添加一行是這樣的:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated); 

其中webBrowswer1_Navigated是你要調用的函數,當事件觸發

0

WebBrowser控件即可。如果你想在一個線程中使用一個WebBrowser實例,你需要創建你的線程並且調用Thread.SetApartmentState(ApartmentState.STA);