1

まず、私が必要としているのは--n WebBrowser-sで、それぞれが独自のウィンドウで独自の仕事をしています。ユーザーは、それらすべて、または1つだけ(またはなし)を表示し、それぞれに対してコマンドを実行できる必要があります。ブラウザのないメインフォームがあります。これには、私のアプリケーションのコントロールパネルが含まれています。

重要な機能は、各ブラウザがセキュリティで保護されたWebページにログオンし、可能な限りログインしたままにする必要があることです。まあ、私はそれをしました、しかし私は私のアプローチに何かが間違っているのではないかと心配しています。

質問は:

以下のコードは有効ですか、それとも問題を引き起こす可能性のある厄介なハックですか?

internal class SessionList : List<Session> {

    public SessionList(Server main) {
        MyRecords.ForEach(record => {
            var st = new System.Threading.Thread((data) => {
                var s = new Session(main, data as MyRecord);
                this.Add(s);
                Application.Run(s);
                Application.ExitThread();
            });
            st.SetApartmentState(System.Threading.ApartmentState.STA);
            st.Start(record);
        });
    }

    // some other uninteresting methods here...

}

何が起きてる?SessionはFormを継承するため、フォームを作成し、それにWebBrowserを配置し、Webサイトを操作するメソッドを備えています。WebBrowserはSTAスレッドで実行する必要があるため、ブラウザーごとに1つずつ提供します。その中で最も興味深い部分はですApplication.Run(s)。新しく作成されたフォームを生き生きとインタラクティブにします。次Application.ExitThread()は、ブラウザウィンドウが閉じられ、そのコントロールが破棄された後に呼び出されます。メインアプリケーションは、残りのクリーンアップジョブを実行するために存続します。

ユーザーが「終了」または「シャットダウン」オプションを選択すると、最初にブラウザスレッドが終了するため、Application.ExitThread()と呼ばれます。それはすべて機能しますが、「メインGUIスレッド」について読むことができるところならどこでも-そしてここで-私は多くのGUIスレッドを作成しました。メインフォームと新しいフォーム(セッション)間の通信は、を使用してスレッドセーフなメソッドで処理しInvoke()ます。それはすべて機能します、それでそれは正しいですか、それとも間違っていますか?

Application.Run()1つのアプリケーションで複数回使用することですべてが正しいですか?:)醜いハックまたは通常の練習?セッションフォームスレッドからWebBrowserを起動すると、このコードは終了します。それはなぜ私を打ち負かします。Urlただし、他のスレッドからWebBrowserを(プロパティを変更して)起動した場合は機能します。そのようなアプリケーションで実際に何が起こっているのかをもっと知りたいです。しかし、何よりも、「アプリケーション内のアプリケーション」という私の考えが大丈夫かどうかを知りたいのです。

正確に何をするのかわかりませApplication.Run()ん。それがないと、新しいスレッドで作成されたフォームは完全に応答しなくなりました。どうすればApplication.Run()何度も電話をかけることができますか?それは正確にそれがすべきことをしているように見えますが、それは私には少し文書化されていない機能のようです。クラッシュはWebBrowserコンポーネント自体が原因であるとほぼ確信しています(完全に「管理」および「ネイティブ」ではないため)。しかし、多分それは別のものです。

4

1 に答える 1

4

1つのアプリケーションでApplication.Run()を複数回使用することですべてが正しいですか?:)醜いハックまたは通常の練習?

両方のいくつか;)これは、期待どおりに機能するという点で完全に受け入れられますが、正確には「通常の方法」ではありません。

Application.Run()が正確に何をするのかわかりません。

Application.Run基本的にいくつかのことを行います。まず、SynchronizationContextWindowsフォームを正しく実行するためにプロパティをスレッドにインストールします。次に、そのスレッドでWindowsメッセージ処理を開始します。このスレッドは、スレッドに入るWindowsからのすべてのメッセージを処理します。これにより、フォームが正しく機能します。

これを行うことに特に問題はありませんが、これは標準的な方法ではありません。あなたの設計目標を考えると、別々のスレッド内で各操作を実行しようとするのではなく、別々のプロセスを起動するだけでこれがより適切に機能するかどうか疑問に思います。

于 2012-06-11T16:36:34.100 に答える