DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C# Formの表示

環境/言語:[環境(XP)、使用言語(C#)]
分類:[.NET]

はじめまして326といいます。
まだ始めて間もないですがよろしくお願いします。

3つのフォーム(A,B,C)をランダムに表示させているのですが
20回位フォームを開いたり閉じたりしてると動作が鈍くなってきます。
タスクマネージャでみるとCPU使用率はMaxで7%位です。
またPF使用量は徐々にですが上がっていってます。

どのようにフォームを開いたり閉じたりすればPF使用量が上がらなくなるのでしょうか?

現在は下記のコードで動作させています。
FormA
FormB frmB = new FormB();
frmB.Show();
this.Close();

FormC frmC = new FormC();
frmC.Show();
this.Close();

FormB
FormA frmA = new FormA();
frmA.Show();
this.Close();

FormC frmC = new FormC();
frmC.Show();
this.Close();

FormC
FormA frmA = new FormA();
frmA.Show();
this.Close();

FormB frmB = new FormB();
frmB.Show();
this.Close();

お手数ですがよろしくお願いします。
  • 題名: Re[1]: C# Formの表示
  • 著者: 326
  • 日時: 2004/12/20 18:17:39
  • ID: 8121
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
自己レスです。
書き忘れていました。
FormAはグラフィックが多くラベルが40個位
FormBはラベルとテキストBOXが100個位
FormCはラベルが250個あります。
こんにちは、じゃんぬねっと です。

■No8118に返信(326さんの記事)
> 現在は下記のコードで動作させています。
> FormA
> FormB frmB = new FormB();
> frmB.Show();
> this.Close();
>
> FormC frmC = new FormC();
> frmC.Show();
> this.Close();
>
> FormB
> FormA frmA = new FormA();
> frmA.Show();
> this.Close();
>
> FormC frmC = new FormC();
> frmC.Show();
> this.Close();
>
> FormC
> FormA frmA = new FormA();
> frmA.Show();
> this.Close();
>
> FormB frmB = new FormB();
> frmB.Show();
> this.Close();

これだと、破棄されてないのでは?
ちゃんと Dispose() しちゃってください。
早速の返事ありがとうございます。

Dispose()ですが、各フォームのClosedでDispose()をしてるのですが
これでは駄目なのでしょうか?

また、いろいろ調べてみてGC.Collect()も同様に試したのですが同じ結果です。
326さん、こんばんは。

質問が上がってすぐに色々と考えてみましたが、意味不明です。
なぜ、そんな処理がしたいのでしょうか?
ソレによっては解決法が見つかるかもしれません。
ぺがらぼさん、こんばんは。

> なぜ、そんな処理がしたいのでしょうか?
実は、24時間連続で運転させていると3〜4日で動かなくなる為なんですよ
使用内容は、フォームで設定値を入力し機器に送信、または機器からのデータを表示します。

こんな感じでわかりますでしょうか?
こんにちは じゃんぬねっと です。

■No8123に返信(326さんの記事)
> 早速の返事ありがとうございます。
> Dispose()ですが、各フォームのClosedでDispose()をしてるのですが
> これでは駄目なのでしょうか?
> また、いろいろ調べてみてGC.Collect()も同様に試したのですが同じ結果です。

スタートアップでない Form で単一 Form を表示しては、自分を Dispose() というのを
10000 万回ほど繰り返してみましたが、メモリ使用量は変わりませんでした。
ちなみに、ガベコレ.Collect() しなかった時は、かなりの勢いで増えておりました(w
先に示したコード、どこに書いてあるかで変わってくるような気が...

# Form.Activated() イベントなんて言わないでくださいね...
  • 題名: Re[6]: C# Formの表示
  • 著者: 326
  • 日時: 2004/12/21 8:48:54
  • ID: 8133
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
じゃんぬねっとさん、おはようございます。

> スタートアップでない Form で単一 Form を表示しては、自分を Dispose() というのを
> 10000 万回ほど繰り返してみましたが、メモリ使用量は変わりませんでした。
> ちなみに、ガベコレ.Collect() しなかった時は、かなりの勢いで増えておりました(w
> 先に示したコード、どこに書いてあるかで変わってくるような気が...

Dispose()は、各フォームのClosedでDispose()をしています。
またフォームを開く時はBUTTONのClickイベントで表示させるか
フォームのKeyDownに割り当てて表示させています。

FormB frmB = new FormB();
frmB.Show();
this.Close();
ちっと気になったので出張。
 Form.Closeメソッドをコールしているなら、Disposeする必要はありません。呼ばれています。
See→ http://www.microsoft.com/japan/msdn/library/ja/cpref/html/frlrfsystemwindowsformsformclassclosetopic.asp
≪フォームが閉じると、オブジェクト内で作成されたすべてのリソースが閉じ、フォームが破棄されます。≫
≪モードレス ウィンドウとして表示されている Form で Close メソッドが呼び出された場合は、フォームのリソースが既に解放されている≫

 この場合、非表示のメインフォームと、3つのFormを作り、それぞれの表示/非表示を切り替えるのが最適と思われます。余計なものは作らず、余計な処理もさせないにこしたことはない。
Jittaさん、こんにちは

MSのサイトを見ていろいろしてみたのですがやはり改善されませんでした。

>  この場合、非表示のメインフォームと、3つのFormを作り、それぞれの表示/非表示を切り替えるのが最適と思われます。余計なものは作らず、余計な処理もさせないにこしたことはない。

表示/非表示を切り替えると言うのはHide()で非表示、Show()で表示と言ういみでしょうか?
326さんこんにちは。

> 表示/非表示を切り替えると言うのはHide()で非表示、Show()で表示と言ういみでしょうか?

おそらくそうではないかと。
常駐させるのであれば、私もそうしますね。
メインのコンストラクタなどで3つのフォームのインスタンスを作成しておいて、
以降は Show(), Hide() で表示/非表示を切り替える。
終了時に3つのフォームのCloseメソッドを実行して終了。

また、一つお聞きしたいのですが、

FormA
FormB frmB = new FormB();
frmB.Show();
this.Close();

の4行目はfrmBをCloseさせたいのですか?
最初の書き込みのコードの見方が良く分からなかったのですが、もし、

// FormA のコード
FormB frmB = new FormB();
frmB.Show();
this.Close(); // frmB をクローズ

という意味で使われているとしたら、
そこは this.Close() ではなく、frmB.Close() となります。
私の思い違いであればいいのですが・・・
聖 羅樹さん、こんちは。

>>表示/非表示を切り替えると言うのはHide()で非表示、Show()で表示と言ういみでしょうか?
> おそらくそうではないかと。
> 常駐させるのであれば、私もそうしますね。
> メインのコンストラクタなどで3つのフォームのインスタンスを作成しておいて、
> 以降は Show(), Hide() で表示/非表示を切り替える。
> 終了時に3つのフォームのCloseメソッドを実行して終了。
やはりそうでしたか。
ちょっと試してみますね。

> また、一つお聞きしたいのですが、
> FormA
> FormB frmB = new FormB();
> frmB.Show();
> this.Close();
> の4行目はfrmBをCloseさせたいのですか?
> 最初の書き込みのコードの見方が良く分からなかったのですが、もし、
> // FormA のコード
> FormB frmB = new FormB();
> frmB.Show();
> this.Close(); // frmB をクローズ
> という意味で使われているとしたら、
> そこは this.Close() ではなく、frmB.Close() となります。
> 私の思い違いであればいいのですが・・・

4行目のthis.Close()ですが、FormA のコードで話しますと、
FormAからFormBを表示させるのでFormAをCloseさせたいのです。

4行目をfrmB.Closeだと表示されないと思うのですが。。。
> 4行目をfrmB.Closeだと表示されないと思うのですが。。。

確かにその通りです。しかし、フォームを表示したのち
そのフォームを閉じる前に自分を閉じてしまうのはおかしいのでは?と
思ったため、質問させて頂きました。
それから、FormなどIDisposeを持つクラスの場合、
Disposeメソッドを実行してやらないとメモリが正常に破棄されません。
PF使用量が増えていく原因はそこにあるのではないでしょうか。

FormB frmB = new FormB();
frmB.Show();
frmB.Close();
this.Close();

とすればPF使用量が増えることはないような気がします。
しかし表示した直後に閉じてしまいますが。

A,B,Cがそれぞれ独立して表示されるのでしたら、
やはり個別に表示/非表示を切り替えるほうがいいと思います。
聖 羅樹さん、こんばんは

> それから、FormなどIDisposeを持つクラスの場合、
> Disposeメソッドを実行してやらないとメモリが正常に破棄されません。
> PF使用量が増えていく原因はそこにあるのではないでしょうか。
> FormB frmB = new FormB();
> frmB.Show();
> frmB.Close();
> this.Close();
> とすればPF使用量が増えることはないような気がします。
> しかし表示した直後に閉じてしまいますが。

frmB.Show();の後にfrmB.Close();だと表示しないのでこれでは無理ですね。


> A,B,Cがそれぞれ独立して表示されるのでしたら、
> やはり個別に表示/非表示を切り替えるほうがいいと思います。
このやり方でテストしてみたのですが、エラーで動作しません。

メインのコンストラクタへの書き方が悪いと思うのですが。。。
通常はどのように書けばいいのでしょうか?

答えを求めてしまいましたが、よろしくお願いします。
>>A,B,Cがそれぞれ独立して表示されるのでしたら、
>>やはり個別に表示/非表示を切り替えるほうがいいと思います。
> このやり方でテストしてみたのですが、エラーで動作しません。
>
> メインのコンストラクタへの書き方が悪いと思うのですが。。。
> 通常はどのように書けばいいのでしょうか?

申し訳ありませんが、それぞれのフォームはどのような条件で
表示されるのかを教えていただけませんか?
例えば、
・起動と同時に3つフォームが表示される
・それぞれのフォームから別フォームを表示させるためのボタンがある
・一つのフォームを閉じると別フォームが表示される
・表示される順番は固定
とか。
あと終了条件もお聞きしたいです。
起動したらWindowsのシャットダウンまで起動しっぱなしというなら
話は別ですが。

初めの投稿のコードから動きが思いつかなかったので・・・(汗
聖 羅樹さん、おはようございます。

出張に行っていたので返事が遅れてしまいました。


> 申し訳ありませんが、それぞれのフォームはどのような条件で
> 表示されるのかを教えていただけませんか?

スタートフォーム起動後、タイマーAの20秒後にFormAが起動します。
スタートフォームはタイマーBで2500間隔おきに通信をしています。
通信は通信用Classにあり、スレッドでスタートフォームのタイマーBで呼び出しています。
またFormA,B,C共に通信用クラスを参照しています。
(FormA,B,C共にある通信先の機器にデータを送る為)

FormAにはBボタンとCボタンがあり、それぞれのボタンクリックで各Formを表示させています。
FormBにはAボタンとCボタンがあり、それぞれのボタンクリックで各Formを表示させています。
FormCにはAボタンとBボタンがあり、それぞれのボタンクリックで各Formを表示させています。

// FormA のボタンBのコード
FormB frmB = new FormB();
frmB.Show();
this.Close(); //FormAを閉じる


> あと終了条件もお聞きしたいです。
> 起動したらWindowsのシャットダウンまで起動しっぱなしというなら
> 話は別ですが。

終了条件はFormA,B,C共にメニューバーを付けていてメニューの中の終了をクリックするとFormENDを表示させています。
FormENDはMessageBox.Show()で表示させYES/NOボタンの選択で終了します。

これでわかりますでしょうか?
326さん、こんにちは。

> スタートフォーム起動後、タイマーAの20秒後にFormAが起動します。
> FormAにはBボタンとCボタンがあり、それぞれのボタンクリックで各Formを表示させています。
> FormBにはAボタンとCボタンがあり、それぞれのボタンクリックで各Formを表示させています。
> FormCにはAボタンとBボタンがあり、それぞれのボタンクリックで各Formを表示させています。
> 終了条件はFormA,B,C共にメニューバーを付けていてメニューの中の終了をクリックするとFormENDを表示させています。
> FormENDはMessageBox.Show()で表示させYES/NOボタンの選択で終了します。

上記の条件にて動作するサンプルを作ってみました。
私の認識違いで動作が違う部分もあるかもしれませんが、
参考にして頂ければ幸いです。
(この記事にはファイル"sampleCS.zip"が添付されていましたが、削除されました。)
聖 羅樹さん、こんにちは。

> 上記の条件にて動作するサンプルを作ってみました。
> 私の認識違いで動作が違う部分もあるかもしれませんが、
> 参考にして頂ければ幸いです。

サンプルありがとうございました。
サンプルを使用してみた結果、PF使用量は増えませんでした。
ありがとうございました。

ただ、サンプルのAppExit()ですが
frmA.Close()でエラーになっていました。

今回の件で色々勉強になりました。
ありがとうございました。
解決済み!
326さんおはようございます。

> ただ、サンプルのAppExit()ですが
> frmA.Close()でエラーになっていました。

上記エラーについてですが、それぞれのフォームを×ボタンなどで
閉じてしまうと、AppExit()メソッドにて frmA.Close() がエラーになります。
ShowFormAメソッドでも同じくエラーが出るはずです。
これは既にそのフォームが破棄されているためなのですが、
Form A,B,C を勝手に閉じられないよう、
×ボタンや Alt+F4 などで閉じられようとする時はCloseをキャンセルしてやれば、
ユーザがそのフォームを破棄してしまうことはなくなりますので、このエラーはなくなります。
それでももちろん例外処理を入れておくに越したことはないのですが。

サンプルということで、そういった細かい部分は記述していません。
そちらの環境、仕様に併せてカスタマイズして下さい。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板