2011-05-01 139 views
3

我使用WebBrowser控件導航到WordPress博客的登錄頁面。 頁面加載正常,但每當我嘗試從一個線程訪問WebBrowser。我得到一個特定的cast是無效的異常。另外在調試時,一切都會凍結大約5秒鐘。調試時,我嘗試訪問該控件。我會在所有成員變量上超時出錯。WebBrowser控件:「指定的轉換無效。」

//in constructor of main form 
Thread.CurrentThread.ApartmentState = ApartmentState.STA; 
this.CheckForIllegalCrossThreadCalls = false; 

mainThreadHandle = new Thread(mainThread); 
mainThreadHandle.Start(); 

private void mainThread() 
{ 
    wbMain.Navigate("http://example.com/"); 

    //navigating is set to false in the document complete event. 
    navigating = true; 

    while (navigating == true) 
     Thread.Sleep(5000); 

    try 
    { 
     //Where I get the issues 
     MessageBox.Show(wbMain.DocumentText); 
    } 
    catch (Exception e) 
    { 

    } 

    Thread.Sleep(1000); 
} 
+0

你可以發佈'指定的轉換是無效的異常嗎? – 2011-05-01 14:01:13

+0

您的代碼中存在一個錯誤。你需要看看你的代碼並找到錯誤。 – SLaks 2011-05-01 14:02:11

+1

代碼因爲您將其發送到睡眠5000毫秒而凍結5秒。 – 2011-05-01 14:24:27

回答

9

web瀏覽器是在引擎蓋下一個COM組件。一個公寓通過一個公寓,COM負責以線程安全的方式調用它的方法。你的Navigate()調用就是出於這個原因,它實際上是在UI線程上執行的。不起作用的是DocumentText屬性,它是在.NET包裝器中實現的,它們有些讓人失望。當CLR中的COM互操作支持發現MTA中的線程試圖訪問駐留在STA上的組件的屬性時,它會發生爆炸。

您對SetApartmentState()的調用不正確。它是在錯誤的線程上創建的,UI線程已經是STA。此外,它不會炸彈的原因,你不能改變線程啓動後的公寓狀態。你必須在你創建的Thread對象上調用它。它仍然不能解決你的問題,兩個STA線程不兼容。

解決問題的兩種基本方法。第一個是你在單獨的STA線程上創建WebBrowser對象本身。 this answer中的代碼向您展示瞭如何做到這一點。

您以這種方式創建的瀏覽器不能在窗體上顯示。這是第二種方式,使用Control.Invoke()自己編組呼叫。然而,這樣做毫無意義,無論如何,您的所有代碼都在UI線程上執行,並且沒有併發性。這裏沒有免費的午餐。在線程上運行只會讓你頭疼。如果您需要時間來處理文檔文本,則在獨立的線程上運行代碼。

+0

感謝您的信息..我有一個相關的問題作爲延伸到這個http://stackoverflow.com/questions/22820382/how-to-update-documenttext-with-another-documenttext – Lijo 2014-04-02 19:19:25

相關問題