WebBrowser 控件:“指定的转换无效。”

2024-04-17

我使用 WebBrowser 控件导航到 WordPress 博客的登录页面。 页面加载正常,但每当我尝试从线程访问 WebBrowser 时。我得到一个特定的强制转换无效的异常。另外,在调试时,一切都会冻结大约 5 秒。调试时,我尝试访问控件。我的所有成员变量都出现超时错误。

//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);
}

WebBrowser 是一个底层的 COM 组件。作为一种单元线程的 COM,COM 负责以线程安全的方式调用其方法。由于这个原因,您的 Navigate() 调用有效,它实际上是在 UI 线程上执行的。不起作用的是 DocumentText 属性,它是在 .NET 包装器中实现的,并且他们在某种程度上弄乱了代码。当 CLR 中的 COM 互操作支持注意到 MTA 中的线程试图访问 STA 上的组件的属性时,它就会崩溃。

您对 SetApartmentState() 的调用不正确。它是在错误的线程上创建的,UI 线程已经是 STA。这也是它不会崩溃的原因,在线程启动后您无法更改线程的单元状态。您必须在您创建的 Thread 对象上调用它。它仍然没有解决你的问题,两个 STA 线程不兼容。

解决问题的两种基本方法。第一个是在单独的 STA 线程上创建 WebBrowser 对象本身。代码在这个答案 https://stackoverflow.com/questions/4269800/c-webbrowser-control-in-a-new-thread/4271581#4271581向您展示如何做到这一点。

您以这种方式创建的浏览器也无法在您的表单上可见。这是第二种方法,使用 Control.Invoke() 自行编组调用。然而,这样做是毫无意义的,无论如何,所有代码都在 UI 线程上执行,你不会获得并发性。这里没有免费的午餐。在线程上运行它只会让你头疼。如果您需要时间处理文档文本,请运行that代码在单独的线程上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebBrowser 控件:“指定的转换无效。” 的相关文章

随机推荐