0

我正在努力寻找一个好的标题,因为我已经解决了我的问题。我只需要解释我是如何解决它的……因为我正在研究我今天刚刚发现的东西,现在对我来说可能还不清楚。

因此,为了恢复我的问题解决,这里是我解决问题的方式,以及我不明白的地方。

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

我决定从主线程中退出一些爬行工作,因为这非常耗时并且冻结了我的应用程序。

我以前这样做的方法是每个搜索方法的 BackgroundWorker(每个网站一个)。它适用于每个网站,除了带有 WebBrowser 的网站。我遇到了一个异常:“无法获取 'WebBrowser' 控件的窗口句柄。不支持无窗口 ActiveX 控件。”。

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

它也没有工作,同样的例外。我找到了这个答案(http://stackoverflow.com/questions/4269800/webbrowser-control-in-a-new-thread)这对我有很大帮助(我改变了一点答案代码让它像这是面向问题的)

所以现在:

我单击一个按钮,它会创建一个 BackgroundWorker。在 BackgroundWorker 内部,调用了 launchSearch 方法。在这个 launchSearch 方法中,我创建了一个新线程,它正在完成我需要的所有工作(这个线程的创建方式与我上面链接的解决方案几乎相同),我将“hasActiveThread”布尔值设置为 true,而线程尚未完成工作。工作完成后,我得到结果并释放我的 BackgroundWorker。

困扰我的是,我真的不明白为什么在我的 BackgroundWorker“DoWork”方法中创建表单在尝试导航到 url 时无法正常工作。如果您至少可以帮助我理解为什么解决方案必须如此“复杂”,以及这背后的原因,我将非常感激!

Al_th

4

1 回答 1

2

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

于 2012-07-27T11:33:11.507 回答