- PR -

Formを閉じる際のリソース解放について

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-07-08 11:34
引用:

梶さんの書き込み (2006-07-07 09:12) より:

元請け会社の方からは、ここのURLのチェックシートを全部
チェックしろ等と言われ、かなり混乱している状況です。
http://www.microsoft.com/japan/msdn/enterprise/pag/scalenetcheck06.asp


ふーーん。元請け会社に言いたいね。
引用:

効率的なリソース管理を心掛けて設計する。
効率的な例外管理を心掛けて設計する。


「効率的」を定義してください。何を持って「効率的」とし、何を「非効率」とするのか。

チェックリストを使うのはいいけど、その中の内容が理解できていないと意味がない。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-07-08 12:05
引用:

じゃんぬねっとさんの書き込み (2006-07-07 16:13) より:
引用:

ちなみに・・・
DataSetで「DataSet.Tables.Add(DataTabel)」した後のDataTableは、Disposeしても
DataSetに影響はないでしょうか?
DataGridで「DataGrid.SetDataBinding(DataSet, DataSet.Tables[0].TableName)」
した後のDataSetは、DisposeしてもDataGridに影響はないでしょうか?


是非、'実際に' お試しになって、インスタンスについての理解を深めてください。
先ほどの繰り返しになってしまうかもしれませんが、実証することが大事だと思います。
(それは自分の中に刻まれやすいものです)


これ、この考え方自体には賛成なんですけども、試した結果が理解として正しいかどうかは
別の問題であるってところが、結構頭が痛いんですよね。
たとえばDisposeを実行した場合に、常にそのインスタンスは使用不可になるような
実装であれば検証できますけど、普通はそれは保証できない。

例えばFormをDisposeした場合、単純なメンバ変数を返すプロパティがあって、
その実装がDisposeされたかのチェックをしていないと、その問題なく動いてしまう。
でも普通の感覚ではDisposeした後のオブジェクトは使用するべきではないだろうし、
いつか実装でプロパティにDisposeされたかのチェックが追加されたらアウト。

よって使う側としては、Disposeしたらもう使えない(使えることは保証されない)
くらいをお約束としておくくらいしかできません。


ところで質問者の話ですけど、DataSetとかDataTable以前に、Form等の破棄は
問題ないんでしょうか?
画面がおかしくなるっていうあたりがどうも怪しく見えるので。
※するべき論はおいといて、普通DataSetをDisopseしなかったからって、
 リソースリークの問題は発生しないですよね、多くの場合?
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-07-08 12:34
引用:

なちゃさんの書き込み (2006-07-08 12:05) より:

これ、この考え方自体には賛成なんですけども、試した結果が理解として正しいかどうかは別の問題であるってところが、結構頭が痛いんですよね。


これは、'影響がある' について、ですよね。
(また突っ込まれちゃいましたねw)

引用:

例えばFormをDisposeした場合、単純なメンバ変数を返すプロパティがあって、
その実装がDisposeされたかのチェックをしていないと、その問題なく動いてしまう。
でも普通の感覚ではDisposeした後のオブジェクトは使用するべきではないだろうし、
いつか実装でプロパティにDisposeされたかのチェックが追加されたらアウト。


これは、非常にわかりやすい例のひとつですね。

# Disposed プロパティをガード句として置く、なんてのはアリなんでしょうか...

引用:

よって使う側としては、Disposeしたらもう使えない(使えることは保証されない)
くらいをお約束としておくくらいしかできません。


ですので、using で範囲を制限するんでしょうけど、広域な変数はこの限りじゃないですね。

引用:

ところで質問者の話ですけど、DataSetとかDataTable以前に、Form等の破棄は問題ないんでしょうか?
画面がおかしくなるっていうあたりがどうも怪しく見えるので。


Form が閉じられるタイミングで HogeClass も破棄するのかという質問だったので、
破棄しているのかと思いましたが、"閉じたタイミングで" としか書かれてませんね...
ShowDialog メソッドで表示しているとすれば、ビンゴかもしれません。

引用:

※するべき論はおいといて、普通DataSetをDisopseしなかったからって、
 リソースリークの問題は発生しないですよね、多くの場合?


べき論はおいといて、(するべき派が怖いので書いておく) 仰るとおりでしょうね。
耐久テストのような状態だと微妙かもしれませんが、仰るとおり多くの場合は問題ない思います。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-07-08 13:21
引用:

※するべき論はおいといて、普通DataSetをDisopseしなかったからって、
 リソースリークの問題は発生しないですよね、多くの場合?



DataSet が Dipose() を備えているのは、ひとえに Component 派生だからでしょう。

あえてアンマネージリソースを抱き込んだクラスをフィールドにねじ込んだりしない限り、DataSet 自体はマネージメモリの塊のはずなので Dispose() しなくても問題は起きないはずです。(あまりにも巨大な DataSet を何個も使うとまずいかもしれませんが)
ベテラン
会議室デビュー日: 2005/05/16
投稿数: 85
お住まい・勤務地: 千葉県在住
投稿日時: 2006-07-10 09:43
皆さん、お休み中(?)にも係わらず、有難うございます。

引用:

なちゃさんの書き込み (2006-07-08 12:05) より:

ところで質問者の話ですけど、DataSetとかDataTable以前に、Form等の破棄は
問題ないんでしょうか?
画面がおかしくなるっていうあたりがどうも怪しく見えるので。
※するべき論はおいといて、普通DataSetをDisopseしなかったからって、
 リソースリークの問題は発生しないですよね、多くの場合?



確かに、DataSet/DataTableを使用している各メソッド内にDisposeを追記して
テストをしてみましたが、消費メモリに変化は見られませんでした。
ご指摘の通り、Formのオープン/クローズ周りを再度調査しようと思います。

引用:

じゃんぬねっとさんの書き込み (2006-07-08 12:34) より:

Form が閉じられるタイミングで HogeClass も破棄するのかという質問だったので、
破棄しているのかと思いましたが、"閉じたタイミングで" としか書かれてませんね...
ShowDialog メソッドで表示しているとすれば、ビンゴかもしれません。



対象フォームは、モードレス(Showメソッド表示)です。
と、言う事は、何か見落としている点がありそう・・・という事でしょうか(汗
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-07-10 09:58
引用:

梶さんの書き込み (2006-07-10 09:43) より:

対象フォームは、モードレス(Showメソッド表示)です。
と、言う事は、何か見落としている点がありそう・・・という事でしょうか(汗


それを確認するためにも、Form のメンバを洗い出す必要があります。
そしてそれは、我々にはできないんですよ... (>_<)

検討がつかないようであれば、コメントアウトをするなりして、
再現できるミニマム コードを見つけることです。
そうすれば、答えは自ずと 1 つに絞られます。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
iStation
大ベテラン
会議室デビュー日: 2003/12/08
投稿数: 158
投稿日時: 2006-07-10 10:15
当ずっぽうですが、
何かOCXを使われていませんか?
_________________
IEEE-CSDP 2004-2007
ベテラン
会議室デビュー日: 2005/05/16
投稿数: 85
お住まい・勤務地: 千葉県在住
投稿日時: 2006-07-10 18:28
え〜中間報告・・・と言う訳でもないのですが・・・

対象Form内にあるnewを全て検索し、怪しそうなところにDisposeを記述したり・・・
FormのClosedイベントにthis.Disposeを記述したり・・・
Form内で作成しているクラスで、オブジェクトのインスタンスを作成しているものに
IDisposable.Disposeを実装したりして、デバッグモードでテストしたところ
メモリ使用量にあまり変化がなく(涙

そのまま延々道処理を繰り返していたところ、前回のテスト時同様チェックボックスの
表示がおかしくなったのですが、その際に例外エラーが出ている事が判明しました。

-----
使用されたパラメータが無効です。

at MainMenu.Application_ThreadException(Object sender, ThreadExceptionEventArg e) MainMenuソースPath.ソース名.cs(1806)
at ThreadContext.OnThreadException(Exception t)
at Application.OnThreadException(Exception t)
at Control.WndProcException(Exception e)
at ControlNativeWindow.OnThreadException(Exception e)
at NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationnContext context)
at Application.Run(Form mainForm)
-----

通常は例外など出ないので、フォームを開く処理周りを調べてみたところ
単純にフォームを「Form f = new Form()」で作成しているわけではなく

-----
Assembly assembly = Assembly.LoadFrom(FileName);
Type type = assembly.GetType(ClassName, true);
object instance = Activator.CreateInstance(type,Args);
Form f = (Form)instance;
-----

のように、DLLからフォームのインスタンスを取得している事が判明しました。
もしかしたら、この辺りで、リソースの解放忘れか、もっと他にまずい事をしてないか
鋭意調査中です。

#ちなみに、OCXは今回のForm内では使用してないです。

また、何か判ったら報告します。

スキルアップ/キャリアアップ(JOB@IT)