WebBrowser在BackgroundWorker理解的STAThread中导航



我很难找到一个好的标题,因为我已经解决了我的问题。我只需要解释一下我是如何解决的。。。因为我正在深入研究我今天刚刚发现的东西,现在可能还不清楚。

所以为了恢复我的问题解决,这里是我解决问题的方法,也是我不理解的。

我正在设计一个WindowsForm应用程序,它可以爬进网站以检索一些数据。我有几个不同的网站可以爬进去,每个都不一样。我使用的基本方式是使用WebRequest。然而,有一个网站强迫我模拟点击,所以对于这个特定的网站,我使用WebBrowser控件来调用特定的javascript函数。

我决定离开主线程进行一些爬行工作,因为这确实很耗时,并冻结了我的应用程序。

我过去做这件事的方式是每个搜索方法的BackgroundWorker(每个网站一个)。它适用于除使用WebBrowser的网站之外的所有网站。我收到一个异常:"无法获取"WebBrowser"控件的窗口句柄。不支持无窗口ActiveX控件。".

我在网上发现我不能使用WebBrowser控件,因为我不在构建WebBrowser的线程中。我决定创建一个Form,将WebBrowser封装在BackgroundWorker的DoWork方法中,而不是原始Form,并为此WebBrowser调用Navigate()方法。

除了同样的例外,它也不起作用。我找到了这个答案(http://stackoverflow.com/questions/4269800/webbrowser-control-in-a-new-thread)这对我帮助很大(我稍微修改了一点答案代码,使其能够工作,因为它是面向问题的)

所以现在:

我点击一个按钮,它就创建了一个BackgroundWorker。在BackgroundWorker内部,将调用launchSearch方法。在这个launchSearch方法中,我创建了一个新线程,它正在完成我需要的所有工作(这个线程的创建方式与我上面链接的解决方案几乎相同),当线程还没有完成工作时,我将"hasActiveThread"布尔值设置为true。工作完成后,我得到结果并发布我的BackgroundWorker。

让我困扰的是,我真的不明白为什么在我的BackgroundWorker"DoWork"方法中创建一个Form在尝试导航到url时不能正常工作。如果你至少能帮助我理解为什么解决方案必须如此"复杂",以及背后的原因,我将非常感谢!

第Al个

您的解决方案不起作用,因为BackgroundWorked运行的所有新线程都是在没有运行Message Loop的情况下启动的。任何用户交互操作都可以通过Windows消息机制进行。看见http://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows和http://msdn.microsoft.com/en-us/library/windows/desktop/ms644928%28v=vs.85%29.aspx详细信息。简单地创建Form对象不会初始化消息循环。为了运行它,您可以调用Form.Show或Form.ShowDialog方法,或Application.Run(…)方法。在工作示例中,消息循环是用Application.Run()方法启动的。

最新更新