- 締切済み
C# イベント動作について(スレッド使用時)
現在、VS2005 Pro C#を使用してWindowsアプリケーションを作成しております。 Form1, Form2を作成し、それぞれの最大化最小化の動作を連動させる(Form1が最大(小)化したらForm2も最大(小)化する)ため以下のようなコードを作成しました。 ・Form1 //Form2の作成とResizeイベントの追加 Form2 fm2; public Form1() { InitializeComponent(); fm2 = new Form2(); fm2.Show(this); } private void Form1_Resize(object sender, EventArgs e) { fm2.WindowState = this.WindowState; } ・Form2側 //Resizeイベントの追加 private void Form2_Resize(object sender, EventArgs e) { this.Owner.WindowState = this.WindowState; } シングルスレッドのプログラムの場合これで問題なく動作します。 しかし、現在作成しているプログラムで、Form2にForm1で作成した別スレッドで計算した結果を表示させるという事をしているのですが、この場合片側のResizeイベントがうまくいかず最大最小化の動作が連動しない時があります。 デバッグで確認すると、シングルスレッドの場合、Form1,Form2のどちらかの最大最小ボタンを押せば、お互いのResizeイベントが交互に動作します。 しかし、作成しているプログラムの場合、押した側でしかResizeイベントが発生しない時がありこれが原因だと考えています。 (具体的にいうと >fm2.WindowState = this.WindowState; または >this.Owner.WindowState = this.WindowState; ↑を通っているが、別のForm側でも起こるはずのResizeイベントが発生しません。 ) シングルスレッドの場合は問題なく動作していることから、おそらく、計算に使っている別スレッドが原因かと考えていますが、スレッドを使う上での注意点がありましたらアドバイスいただけないでしょうか?
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
別スレッドからフォームを操作するには、Invokeを使ってフォームを生成したスレッドに呼び出させる必要があります。これが原因かどうかは分かりませんが、参照URLに詳しく載っているので参考にしてみてください。
- sonata1229
- ベストアンサー率36% (76/206)
つまり、計算処理している別スレッドからこのイベントを 呼び出しているんですよね?? デバック時にVSが教えてくれるかもしれませんが、 コントーラ(Form等)を扱っているスレッドとは異なる スレッドからコントローラ制御するにはデリゲートを使わなければなりません。 例えば、別スレッドから画面のリフレッシュをさせたい場合だと、 delegate void hogeRefreshDelegate(); private hogeRefresh() { if (this.InvokeRequired) { this.Invoke(new hogeRefreshDelegate(hogeRefresh)); } else { this.Refresh(); } } とデリゲート宣言しておいて、 別スレッドから、「hogeRefresh()」を呼び出せばいいです。 デリゲートでググればいろいろとわかりやすいサイトがあるので、 参考にしてみてください。
補足
ご回答ありがとうございます。 >つまり、計算処理している別スレッドからこのイベントを >呼び出しているんですよね?? こちらは私の説明がわかりにくく、申し訳ありません。 現在、Form1、Form2は同時に画面に表示されています。 イベントが呼ばれるのは、スレッドからではなくそれぞれのFormの最大(最小)ボタンをマウスで押した時になります。 具体的には Form2のDataGridViewに計算結果を表示するという事をスレッドにて行っているのですが、この表示の最中(終わった後もですが)にForm1の最大化ボタンを押すと >m2.WindowState = this.WindowState; とForm2のWindowStateを変更しているつもりですが、Form2側で Resizeイベントが発生しないといった次第です。 (シングルスレッドのサンプルでは必ず発生しました。) >スレッドからコントローラ制御するにはデリゲートを使わなければなりません。 先ほど説明させていただいた >Form2のDataGridViewに計算結果を表示するという という作業はdelegateを使っています。 もしこのdelegateによるスレッドセーフの対応をしていない場合、実行した時にErrorが出ると思うのですが、この最大(最小)化ボタンに関しては出てきません。 しかし、私もこの辺りが怪しいと考えています。
補足
ご回答ありがとうございます。 参考にさせていただきます。