2011-05-01 136 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

相关问题