私の目標
メインの処理スレッド(非GUI)を使用し、必要に応じて独自のバックグラウンドスレッドでGUIをスピンオフできるようにし、メインの非GUIスレッドを引き続き機能させたいと考えています。言い換えれば、メインの非GUIスレッドをGUIスレッドの所有者にし、その逆はしたくないということです。これがWindowsフォーム(?)でも可能かどうかはわかりません
バックグラウンド
IComponent
コントローラーがアセンブリを動的にロードし、単一のメソッドで共通のインターフェイスを実装するクラスをインスタンス化して実行するコンポーネントベースのシステムがありますDoStuff()
。
ロードされるコンポーネントは、xml構成ファイルを介して、およびのさまざまな実装を含む新しいアセンブリを追加することによって構成されますIComponent
。コンポーネントは、メインアプリケーションにユーティリティ機能を提供します。メインプログラムがそれを実行している間、たとえば原子力発電所を制御している間、コンポーネントは(独自のスレッドで)ユーティリティタスクを実行している可能性があります。たとえば、データベースのクリーニング、電子メールの送信、プリンターでの面白いジョークの印刷などです。私が望んでいるのは、これらのコンポーネントの1つがGUIを表示できるようにすることです。たとえば、前述の電子メール送信コンポーネントのステータス情報を表示できます。
システム全体の寿命は次のようになります
- アプリケーションが起動します。
- ロードするコンポーネントの構成ファイルを確認してください。それらをロードします。
- コンポーネントごとに、実行
DoStuff()
して初期化し、独自のスレッドで独自の生活を送るようにします。 - 主なアプリケーションを続けてください-仕事の王様、永遠に。
コンポーネントがでGUIを起動した場合、まだポイント3を正常に実行できていませんDoStuff()
。GUIが閉じられるまで停止するだけです。そして、GUIが閉じられるまで、プログラムはポイント4に進みません。
これらのコンポーネントが独自のWindowsフォームGUIを起動できるようになっていると便利です。
問題
コンポーネントがGUIを起動しようとするとDoStuff()
(コードの正確な行はコンポーネントの実行時です)、コンポーネント、つまりシステムはGUIが閉じられるまでその行Application.Run(theForm)
で「ハング」します。Application.Run()
さて、起動したばかりのGUIは、期待どおりに正常に機能します。
コンポーネントの例。1つはGUIとは何の関係もありませんが、2つ目はピンクのふわふわのウサギが入ったかわいいウィンドウを起動します。
public class MyComponent1: IComponent
{
public string DoStuff(...) { // write something to the database }
}
public class MyComponent2: IComponent
{
public void DoStuff()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
// I want the thread to immediately return after the GUI
// is fired up, so that my main thread can continue to work.
}
}
私は運が悪かったのでこれを試しました。独自のスレッドでGUIを起動しようとしても、GUIが閉じられるまで実行は停止します。
public void DoStuff()
{
new Thread(ThreadedInitialize).Start()
}
private void ThreadedInitialize()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form());
}
GUIをスピンオフして、後で戻ることは可能Application.Run()
ですか?