Dra*_*ake 2 .net c# webbrowser-control winforms
我使用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);
}
Run Code Online (Sandbox Code Playgroud)
WebBrowser是一个COM组件.一个公寓线程,COM负责以线程安全的方式调用其方法.您的Navigate()调用适用于该原因,它实际上是在UI线程上执行的.什么不起作用的是DocumentText属性,它是在.NET包装器中实现的,它们在某种程度上弄错了代码.当CLR中的COM互操作支持注意到MTA中的线程试图访问存在于STA上的组件的属性时,它会发生爆炸.
您对SetApartmentState()的调用不正确.它是在错误的线程上创建的,UI线程已经是STA.也就是它没有炸弹的原因,你不能在它启动后改变一个线程的公寓状态.您必须在您创建的Thread对象上调用它.它仍然无法解决您的问题,两个STA线程不兼容.
解决问题的两种基本方法.第一个是您在单独的STA线程上创建WebBrowser对象.此答案中的代码向您展示了如何执行此操作.
您以这种方式创建的浏览器也不能在表单上显示.这是第二种方式,使用Control.Invoke()自行编组调用.这样做是没有意义的,无论如何你的所有代码都在UI线程上执行,你没有得到并发.这里没有免费的午餐.在线程上运行它只会让您头疼.如果您需要时间来处理文档文本,则在单独的线程上运行该代码.
| 归档时间: |
|
| 查看次数: |
4717 次 |
| 最近记录: |