まず、私が必要としているのは--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コンポーネント自体が原因であるとほぼ確信しています(完全に「管理」および「ネイティブ」ではないため)。しかし、多分それは別のものです。