我正在努力寻找一个好的标题,因为我已经解决了我的问题。我只需要解释我是如何解决它的……因为我正在研究我今天刚刚发现的东西,现在对我来说可能还不清楚。
因此,为了恢复我的问题解决,这里是我解决问题的方式,以及我不明白的地方。
我正在设计一个爬入网站以检索一些数据的 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