- - PR -
TreeViewの再帰的に呼び出しについて
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2009-03-16 12:23
Kingさん
たぶん、「using」でくくっているので、処理完了時にリソース破棄(というか、ガベージさんよろしくって感じですかね。) されることを期待していると思います。 そのため、明示的なクローズがないのだと思います。 (あんまり行儀がいいとはいえないかもしれないけど。) あ、横道それました。すいません。 [ メッセージ編集済み 編集者: かずい 編集日時 2009-03-16 15:49 ] | ||||
|
投稿日時: 2009-03-16 12:37
かずいさん
そうですねー。 Dispose に Close を兼任させるっていうのが GC まかせだと破棄されるのがはっきりしない (不具合の原因になりえる) ので私は絶対しません。 というか皆さんやってらっしゃるんでしょうか。 | ||||
|
投稿日時: 2009-03-16 14:29
お世話になります。
> サンプルを見直したほうがよいと思います。....考え方が誤っていると思われます 見直しました。なんとなく意味がわかってきました。 はっきりと理解できたわけではありませんが、SQLへの次の呼び出し部分の考え方が間違っていたようです。 子が親の印と言うかアドレスみたいな一意的なしるしが欠けていました。それを追加しパラメータの箇所を追加してやることでうまくいくようになりました。 それと、using() の使い方について議論があるようですが、ガバレージに任すのは、危険ですか? 今回は、サンプルよりコピペしてきたので気にしていませんでしたが、実際のところそうなんでしょうか?MSのヘルプには、「不要になったオブジェクトの格納用のメモリが自動的に解放されます。メモリは常に解放されるわけではありません。CLR がガベージ コレクションの実行を決定したときにメモリが解放されます。」とあり、解放は、タイミングによりけり的なことが書いてあります。 今回のコードは、とりあえず下記のように変更してみました。
| ||||
|
投稿日時: 2009-03-16 14:55
争点はそこじゃないっす。DBのクローズをDisposeに任せちゃうのが気持ち悪いって話だと思います。usingがDisposeをやってくれてるのはわかりますよね?一般的な最近のDBではDisposeでCloseしてくれてると思うけど、明示されてない(ヘルプ等に記載がない)DBもあるから、他人任せにしないで自分でやったほうがConnectionのCloseが忘れられて参照だけ消えちゃうっていう事故も起きなにくいっと言うことではないでしょうか。 ちなみに、「using」の外でCloseしたら、開放されているかもしれないオブジェクトのメソッドを呼ぶことになりますが、それってヤバくないですか?例外が発生すると思うのですが・・・ | ||||
|
投稿日時: 2009-03-16 15:09
コネクションプールのサイズ以上に再帰呼出が発生したら、コネクションリークになりませんか?
という事を、 King さん は言いたいのではないでしょうか? ミニマムコード
| ||||
|
投稿日時: 2009-03-16 15:39
セラフさん
お ださん ありがとうございます。 その通りです。 GCに任せると Open しているコネクションが複数存在するかもしれない・・・。 この時、コネクションプールが最大数を超える可能性があるかも・・・。 って思うから明示的に Close したいんです。 例え Close してたとしても個人的には何回も Open したくないです。 (今回は関係ないですがトランザクション処理もしにくいし) 下記のようなイメージをしています。
他には上記のコードのConnection を Command に置き換えて Parameters 以外の CommandText 等のプロパティはずっと同じものを使って Parameters だけ DB 処理時に置き換えると言うのをやった事があります。 using の外で Close する発想は今までありませんでした。 あとガバレージじゃなくてガベージコレクション(GC)ですよね? | ||||
|
投稿日時: 2009-03-16 15:52
ギャーおいらが、打ち間違ってる。
恥ずかしいから編集しちゃいました。 セラフさん お ださん その通りですね。 「お行儀がいい」という表現で伝わり難くなってしまった。 フォローありがとうございます。 | ||||
|
投稿日時: 2009-03-16 23:00
私的にはIDisposable.DisposeでCloseせず、アンマネージリソースを残すクラスはIDisposableを正しく実装できているとは思えません。
http://msdn.microsoft.com/ja-jp/library/system.idisposable.dispose.aspx 現実に存在するかどうかは確かめていないので分かりません。 仮にIDisposable.DisposeメソッドでCloseメソッドを実行しないクラスがいるとします。 そのクラスをメンバー変数に持ち、IDisposable.Disposeメソッドで内部のメンバー変数のCloseメソッドを呼び出すラッパークラスを作って、usingパターンで使うというのは駄目でしょうか? usingスコープはコンパイル時にtry-finallyに展開されるわけですから、usingスコープの中でtry-finallyを書くようだと、usingスコープの意味が薄くなっているので。 # finally句にif (baseCn != null) baseCn.Dispose(); と書けばusingがいらないことになります。 デメリットとしてはラッパークラス経由になるため、微妙にプロパティを経由する手間がかかることでしょうか。 # usingスコープ内の一時変数に代入することで逃げることはできます。
|