0

私はすでに問題を解決していたので、良いタイトルを見つけるのに苦労していました. どうやって解決したのか説明が必要なだけです...今日発見したばかりのものに飛び込んでいるので、今ははっきりしないかもしれません。

したがって、ここで問題の解決を再開するために、私が問題を解決した方法と、私が理解していないことを示します。

データを取得するために Web サイトにクロールする WindowsForm アプリケーションを設計しています。クロールするいくつかの異なる Web サイトがあり、それぞれが異なります。私が使用する基本的な方法は、WebRequest を使用することです。ただし、ある Web サイトではクリックをシミュレートする必要があるため、この特定の Web サイトでは、WebBrowser コントロールを使用して特定の JavaScript 関数を呼び出します。

クロール作業は本当に時間がかかり、アプリケーションがフリーズしたため、メイン スレッドから抜け出すことにしました。

私がこれを行っていた方法は、検索メソッドごとの BackgroundWorker (Web サイトごとに 1 つ) でした。WebBrowser を使用したものを除くすべての Web サイトでうまく機能しました。「'WebBrowser' コントロールのウィンドウ ハンドルを取得できません。ウィンドウのない ActiveX コントロールはサポートされていません。」という例外が発生しました。

WebBrowser が構築されたスレッドにいなかったため、WebBrowser コントロールを使用できないことが Web でわかりました。元の Form ではなく、BackgroundWorker の DoWork メソッド内に WebBrowser をラップする Form を作成し、この WebBrowser に対して Navigate() メソッドを呼び出すことにしました。

同じ例外を除いて、どちらも機能しませんでした。私はこの回答(http://stackoverflow.com/questions/4269800/webbrowser-control-in-a-new-thread)を見つけました。これは私を大いに助けてくれました(コードの回答部分を少し変更して、質問中心でした)

だから今:

ボタンをクリックすると、BackgroundWorker が作成されます。BackgroundWorker 内で、launchSearch メソッドが呼び出されます。この launchSearch メソッド内で、必要なすべての作業を実行する新しいスレッドを作成し (このスレッドは、上記でリンクしたソリューションとほとんど同じ方法で作成されています)、「hasActiveThread」ブール値を true に設定します。スレッドは作業を終了していません。作業が終了したら、結果を取得して BackgroundWorker を解放します。

私を悩ませているのは、URLに移動しようとしたときに、BackgroundWorkerの「DoWork」メソッド内でフォームを作成すると正しく機能しなかった理由がよくわからないことです。少なくとも、解決策が「複雑」でなければならない理由と、その背後にある理由を理解するのを手伝っていただければ、本当に感謝しています!

Al_th

4

1 に答える 1

2

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() メソッドで開始されました。

于 2012-07-27T11:33:11.507 に答える