マルチスレッドWebbrowserコントロールとDocumentCompleted Event
複数のURLを同時に処理する場合、独自のスレッド内の各URLの個別のWebBrowser
コントロールを作成する場合は、効率的に見える場合があります。ただし、このアプローチでは、DocumentCompleted
イベントを確実にトリガーできないことがよくあります。 この記事では、その理由について説明し、解決策を提供します
コントロールの性質にあります。 ActiveXコンポーネントとして、正しく機能するには、シングルスレッドアパートメント(STA)スレッドが必要です。 単に新しいスレッドを開始するだけでは十分ではありません。スレッドには、イベントを処理するためのメッセージループが必要です。 このメッセージループがなければ、WebBrowser
イベント、およびその他の重要なイベントは決して派遣されません。
DocumentCompleted
解決策を示す修正されたコードの例:
重要な変更は、スレッドの実行に
<code class="language-csharp">private void RunBrowserThread(Uri url) { var thread = new Thread(() => { var browser = new WebBrowser(); browser.DocumentCompleted += Browser_DocumentCompleted; browser.Navigate(url); Application.Run(); // Crucial: Starts the message loop }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); } private void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { var browser = (WebBrowser)sender; if (browser.Url == e.Url) { Console.WriteLine($"Navigated to {e.Url}"); Application.ExitThread(); // Safely exits the thread } }</code>
コントロールがApplication.Run()
のようなイベントを受信および処理できるようにします。 ナビゲーションが完了した後、スレッドはWebBrowser
を使用して優雅に終了します。 これにより、適切なイベント処理が保証され、予期しないアプリケーション動作が防止されます。
以上が別のスレッドで使用されたときに、WebbrowserコントロールがDocumentCompletedイベントを発射できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。