C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: disposeすべきobjectの判断は? [1]


(過去ログ 62 を表示中)

[トピック内 39 記事 (21 - 39 表示)]  << 0 | 1 >>

■35681 / inTopicNo.21)  Re[6]: disposeすべきobjectの判断は?
  
□投稿者/ ぱぱいやん (19回)-(2009/05/12(Tue) 13:44:46)
ぱぱいやん さんの Web サイト
No35675 (よりみち さん) に返信

> またWindowsFormのOnPaintイベントでは、
> e.GraphicsをDisposeするといかんといった記述をどこかで見た気が…。

そりゃそうです。
必要があって、他の処理がオブジェクトを生成しているのですから、勝手に破棄をしたら駄目ですよね。
自分が生成したオブジェクトが Dispose を実装したいたら、不要になるタイミングで Dispose すれば良いです。

Dispose って後始末が必要な「何か(メモリに限らず)」って考え方をした方が理解しやすい気がします。

引用返信 編集キー/
■35682 / inTopicNo.22)  Re[7]: disposeすべきobjectの判断は?
□投稿者/ よりみち (3回)-(2009/05/12(Tue) 13:51:30)
No35677 (Hongliang さん) に返信
>>上記をまとめると、IDisposableインターフェースを実装しているクラスは、
>>使用後は、全てDisposeしないといけないのでしょうか?
> 大抵はした方がいい、ぐらいです。「しなければまずい」もあれば「する必要はない」もあります。そのクラス自身の設計にも、利用者側の設計にも依ります。
> スコープ一つですむなら必ず using する、ぐらいならやっといた方がいいでしょう。
> ただ、IDisposable なオブジェクトの参照があっちこっちにちらばってしまう場合、誰がいつ Dispose を呼び出すのか決定できないことも考えられますからね。
>
>>マネージドリソースの場合、
>>GCが回収してくれるので、安易にDisposeすると、
>>レスポンスが悪くなると聞いたことがあります。
> それは Dispose じゃなくて GC.Collect の話だと思います。
> GC が動いたときに生き残ったオブジェクトは寿命が延びるので、不必要な GC.Collect の呼び出しはマネージドメモリの圧迫を招き、次の GC の発動が早くなったりするでしょう。

あー嘘を教わった。これはGC.Collectの話ですね。
MSDNより以下の文言がありました。
---------------------------------------
マネージ リソース (配列など) のみを使用する型は、ガベージ コレクタによって自動的にクリアされるため、このような型で Dispose メソッドを実装しても、パフォーマンス上の利点はありません。
---------------------------------------
呼び出しても、メリットはない場合はあるが、デメリットはなさそうですね。
じゃ、リスク回避で呼んでおいた方がよさそうですね。

>>再利用する場合は、Disposeする必要があるかと思いますが、
>>例えば、DataSetやDataTableなんかも、使用後はDisposeする必要があるんでしょうか?
> 基本的になかったはずですね。基底クラスの MarshalByRefOBject が実装しているから Dispose を持っているに過ぎないはず。
これについても、呼んでもメリットないだけだよってことなんですね。
※今まで呼んでなかったから焦りました(^^;

>>またWindowsFormのOnPaintイベントでは、
>>e.GraphicsをDisposeするといかんといった記述をどこかで見た気が…。
> 自分で作ったものではないものですから。
> // 「自分で作る」の基準も結構曖昧ですけどね。new キーワードなら明らかですが、Graphics.FromImage みたいなメソッドの返値だと……。
なるほど。参考になります。
ありがとうございました。
引用返信 編集キー/
■35683 / inTopicNo.23)  Re[6]: disposeすべきobjectの判断は?
□投稿者/ 魔界の仮面弁士 (1062回)-(2009/05/12(Tue) 13:59:01)
No35675 (よりみち さん) に返信
> 上記をまとめると、IDisposableインターフェースを実装しているクラスは、
> 使用後は、全てDisposeしないといけないのでしょうか?

あえて Dispose しない場合もあります。たとえば、
 Using stm As New FileStream("C:\test.txt", FileMode.Create)
  Dim writer As New StreamWriter(stm)
  writer.WriteLine(Now.ToLongTimeString())
  writer.Flush()
  stm.Seek(0, SeekOrigin.Begin)
  Dim reader As New StreamReader(stm)
  MsgBox(reader.ReadLine(), vbSystemModal)
  stm.Close()
 End Using
というコードを
 Using stm As New FileStream("C:\test.txt", FileMode.Create)
  Using writer As New StreamWriter(stm)
   writer.WriteLine(Now.ToLongTimeString())
   writer.Flush()
  End Using
  stm.Seek(0, SeekOrigin.Begin)
  Using reader As New StreamReader(stm)
   MsgBox(reader.ReadLine(), vbSystemModal)
  End Using
  stm.Close()
 End Using
と書くわけにはいきませんよね。


> マネージドリソースの場合、
ちなみに managed という用語は、Microsoft の公式には(マネージドではなく)マネージと記述する事になっています。


> またWindowsFormのOnPaintイベントでは、
> e.GraphicsをDisposeするといかんといった記述をどこかで見た気が…。
それを Dispose する役割を担うのは、イベントの呼び出し元である Control 自身となります。
イベント引数の e.Graphics は、開発者が生成した物では無いため、Dispose してはいけません。

CreateGraphics のように、開発者自身が生成したインスタンスの場合は、開発者自身が Dispose しなければなりません。


同様の理由から、
 Pen pen1 = new Pen(Color.Red);
 Pen pen2 = Pens.Red;
とあった場合、pen1 は Dispose しなければなりませんが、pen2 を Dispose することは NG です。
引用返信 編集キー/
■35684 / inTopicNo.24)  Re[7]: disposeすべきobjectの判断は?
□投稿者/ よりみち (4回)-(2009/05/12(Tue) 13:59:20)
なんと、数分でこんなに返信が…。

どのコメントもわかりやすかったです。

ありがとうございました。

スレ主さんにパスします。
引用返信 編集キー/
■35685 / inTopicNo.25)  Re[7]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1144回)-(2009/05/12(Tue) 14:06:38)
渋木宏明(ひどり) さんの Web サイト
> 大抵はした方がいい、ぐらいです。

原則は「いつか、どこかで、だれかがしなければならない」としたいなぁ。

> 自分で作ったものではないものですから。
> // 「自分で作る」の基準も結構曖昧ですけどね。new キーワードなら明らかですが、Graphics.FromImage みたいなメソッドの返値だと……。

たとえば、Form に動的に生成したコントロールを追加する場合のように所有権を委譲する場合もあるので、「自分で作った」も基準としては少し弱いです。

同様に、逆のパターン=人が作ったものを自分が解放しなければならない場合もあり得るし。


引用返信 編集キー/
■35686 / inTopicNo.26)  Re[8]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1145回)-(2009/05/12(Tue) 14:15:16)
渋木宏明(ひどり) さんの Web サイト
> じゃ、リスク回避で呼んでおいた方がよさそうですね。

なこたないす。

GC はコストの高い処理なので、頻繁に呼び出すとパフォーマンスが劣化します。

GC.Collect() の明示的な呼び出しが必要になるのは、かなり特殊な状況と考えるべきです。

引用返信 編集キー/
■35689 / inTopicNo.27)  Re[9]: disposeすべきobjectの判断は?
□投稿者/ Hongliang (381回)-(2009/05/12(Tue) 15:17:07)
>>大抵はした方がいい、ぐらいです。
>
> 原則は「いつか、どこかで、だれかがしなければならない」としたいなぁ。

あー、確かに言い過ぎでしたね。
方向としてそっちの方が正しいのは明らかです。
引用返信 編集キー/
■35696 / inTopicNo.28)  Re[9]: disposeすべきobjectの判断は?
□投稿者/ よりみち (5回)-(2009/05/12(Tue) 16:25:45)
No35686 (渋木宏明(ひどり) さん) に返信
>>じゃ、リスク回避で呼んでおいた方がよさそうですね。
>
> なこたないす。
>
> GC はコストの高い処理なので、頻繁に呼び出すとパフォーマンスが劣化します。
>
> GC.Collect() の明示的な呼び出しが必要になるのは、かなり特殊な状況と考えるべきです。
>
自分が記載したのをもう1度読みなおすと、
だいぶ端折ってますね…。

>>じゃ、リスク回避で呼んでおいた方がよさそうですね。
は、
「じゃ、リスク回避でDisposeメソッドは、呼んでおいた方がよさそうですね。」
が正でした m(_ _)m

引用返信 編集キー/
■35702 / inTopicNo.29)  Re[10]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1146回)-(2009/05/12(Tue) 17:01:21)
渋木宏明(ひどり) さんの Web サイト
> 「じゃ、リスク回避でDisposeメソッドは、呼んでおいた方がよさそうですね。」
> が正でした m(_ _)m

いいえ。「とりあえず呼んどきゃ大丈夫だろう」的なのはダメです。

「個々のクラスの仕様をドキュメントなどで確認した上で、状況に応じた適切な対応をする」のが正解です。


引用返信 編集キー/
■35715 / inTopicNo.30)  Re[11]: disposeすべきobjectの判断は?
□投稿者/ なちゃ (281回)-(2009/05/12(Tue) 22:56:59)
>MSDNより以下の文言がありました。
>---------------------------------------
>マネージ リソース (配列など) のみを使用する型は、ガベージ コレクタによって自動的にクリアされるため、このような型で >Dispose メソッドを実装しても、パフォーマンス上の利点はありません。
>---------------------------------------
>呼び出しても、メリットはない場合はあるが、デメリットはなさそうですね。
>じゃ、リスク回避で呼んでおいた方がよさそうですね。

どうにも読み違えているように見えるんですが、MSDNのこの記述は、自分で作成するクラスがIDisposableを実装する必要(意味)があるか、ということについて書いているのではありませんか?
IDisposableな型に対してDisposeを呼び出すべきかという話ではないはずです。

ちょっといろいろ早合点しすぎというか、結論を急ぎすぎというか、簡単にまとめようとしすぎに思います。

引用返信 編集キー/
■35716 / inTopicNo.31)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ hirosi (10回)-(2009/05/12(Tue) 23:20:38)
No35650 (よねKEN さん) に返信
>>StringBuilderなんて良く使うんですが、Dispose呼んでる箇所は1つも無かったりします(;^_^A アセアセ・・・
> というコメントからすると少し誤解があるように思えます。
> StringBuilderクラスはIDisposableを実装していませんので、Disposeを呼ぶこともありません。
> (「Dispose呼んでる箇所は1つも無」で正常ということです)
すみません。勘違いでしたm(__)m

> 開発環境を使われていないか、あるいは、MSDNをインストールされていないという意味でしょうか?
> 例えば、Visual Studio 2008 Express Editionを使われている場合、特に意識せずインストールされていれば、
> ドキュメント(MSDNライブラリ、ヘルプなども同意)もインストールされているはずですので、
> 各クラスの項を参照すれば、IDisposableインタフェースを実装しているかどうかは確認できます。
その件ですが、Jitta on the way さんが
「自分でクラスを作る場合は、ドキュメントに必ず記載します。」
とおっしゃっていたので、私の場合は言ってみれば個人の趣味的な感覚でC#を使っているのでドキュメントは一切書かないと言う意味でしたm(__)m

> おおまかには合っていると思います。細かいことを言えば少し指摘事項はありますが、
> その手の情報については「Dispose Finalize パターン」といったキーワードでWebを検索してみてください。
MSDNのDisposeの実装を読んでみました。
まだ完全に理解し切れていないので、web等でいろいろと調べてみることにします。

ありがとうございました。
引用返信 編集キー/
■35719 / inTopicNo.32)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ hirosi (11回)-(2009/05/12(Tue) 23:33:00)
No35652 (渋木宏明(ひどり) さん) に返信
> C# では
>
> using(xxxx)
> using(xxxx)
> using(xxxx)
> using(xxxx)
> {
> }
これは知りませんでした!
今後、その方法でいきたいと思います。

>>(確実にdisposeするためにはusingを使う事が推奨されているみたいなので)
> IDisposable を明示的に実装していて、かつ Dispose() や Close() のような後片付け用のメソッドを実装していない場合なんかもありますしね。
ちょっと素人丸出しな質問になってしまうのですが、
IDisposable を明示的に実装する とは
class test : IDisposable{
      ^^^^^^^^^^^^^
}
クラスの宣言時に上記の様にするという解釈でよろしいでしょうか?

>IDisposable を明示的に実装していて、かつ Dispose・・・のような後片付け用のメソッドを実装していない場合・・・
というのは
public void Dispose() { }
つまりこういう事でしょうか・・・


引用返信 編集キー/
■35721 / inTopicNo.33)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ hirosi (12回)-(2009/05/12(Tue) 23:42:17)
No35651 (Azulean さん) に返信
>>自分はIDisposableを実装する場合、必ず以下の様にするようにしています。
> こういうページもあります。
> http://msdn.microsoft.com/ja-jp/library/fs2xkftw.aspx
早速見てみました。
一つ疑問なのが、Dispose(false)で呼ぶということはメンバ変数の _resource.Dispose() をしないと言った感じに見えるのですが
仮に、自分自身のDisposeが呼ばれなかった場合、メンバ変数の_resourceもDisposeしない、、と言う事でしょうか?
それとも誰かがDisposeを呼んでくれるのか・・・
う〜ん、難しいです(*_*)

> なお、ファイナライザの時点ではメンバー変数にあるマネージクラスは先にファイナライズ済みかもしれません。
> このため、ファイナライザから呼び出されるコードで、(参照型の)メンバー変数にアクセスするのはよくありません。
ファイナライズ済み、、とは既にDisposeが呼ばれている、、という意味でしょうか?

質問ばかりで申し訳ありません。

引用返信 編集キー/
■35722 / inTopicNo.34)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ hirosi (13回)-(2009/05/12(Tue) 23:45:58)
No35658 (Jitta on the way さん) に返信
> また、「マネージド リソース」と「アンマネージド リソース」の違いも、もう少し知る必要があると思います。
はい。確かにその通りだと思います。
ついつい先走って物作りを始めてしまっておりました。

アドバイスありがとうございました。

引用返信 編集キー/
■35724 / inTopicNo.35)  Re[5]: disposeすべきobjectの判断は?
□投稿者/ hirosi (14回)-(2009/05/12(Tue) 23:57:17)
No35661 (ぱぱいやん さん) に返信
> マネージドリソースが使えるメリットとの相殺じゃないかと思います。
> 単に using や Dispose メソッドを呼び出ば良いだけと考えることもできます。
一通りツリーを見ましたが、Disposeすべきオブジェクトの判断が結構難しいですね(;^_^A アセアセ・・・
今後はドキュメントなどをよーく見て適切にDisposeメソッドを呼ぶようにしたいと思います。

ありがとうございました。
引用返信 編集キー/
■35726 / inTopicNo.36)  Re[6]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1147回)-(2009/05/13(Wed) 00:04:00)
渋木宏明(ひどり) さんの Web サイト
>IDisposable を明示的に実装する とは
>class test : IDisposable{
>      ^^^^^^^^^^^^^
>}
>クラスの宣言時に上記の様にするという解釈でよろしいでしょうか?

違います。
ヘルプとか読んで、ちゃんとお勉強しましょう。

明示的なインターフェイスの実装 (C# プログラミング ガイド)
http://msdn.microsoft.com/ja-jp/library/ms173157(VS.80).aspx

> >IDisposable を明示的に実装していて、かつ Dispose・・・のような後片付け用のメソッドを実装していない場合・・・
> というのは
> public void Dispose() { }
> つまりこういう事でしょうか・・・

インターフェースの明示的実装を理解してから、もう一度考えてみてください。

引用返信 編集キー/
■35729 / inTopicNo.37)  Re[6]: disposeすべきobjectの判断は?
□投稿者/ 魔界の仮面弁士 (1063回)-(2009/05/13(Wed) 01:14:42)
2009/05/13(Wed) 01:35:28 編集(投稿者)

# うまく説明できる自信は無いけれども…。

No35721 (hirosi さん) に返信
>>こういうページもあります。
>>http://msdn.microsoft.com/ja-jp/library/fs2xkftw.aspx
このあたりも。
http://msdn.microsoft.com/ja-jp/library/s9bwddyx.aspx
http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx


> 一つ疑問なのが、Dispose(false)で呼ぶということはメンバ変数の _resource.Dispose() をしないと言った感じに見えるのですが
その通りです。
アンマネージリソースについては、true の場合も false の場合も処分されるように実装しますが、
マネージリソースである _resource については、引数に false を渡した場合には処分しないのです。
(Managed Resorces = .NET が管理している資源、Unmanaged Resources = .NET 管理外の資源)

そしてこの時、Dispose(bool) のオーバーロードは、外部から呼び出せないよう、
protected として宣言されている点にも着目しておいてください。
もし、シールされたクラス(C#:sealed、VB:NotInheritable)にするのであれば、private で OK です。


> 仮に、自分自身のDisposeが呼ばれなかった場合、メンバ変数の_resourceもDisposeしない、、と言う事でしょうか?
Dispose されなかった場合に備える必要がある場合には、保険としてファイナライザを実装し、
その中で、自身が使っていた資源を処分するように記述します。これにより、少なくとも GC さえ
発動されれば、そのタイミングで Dispose されることになります。いつ発動するかは分かりませんが。

この場合、ファイナライズの時点で処分させるのはアンマネージリソースだけです。マネージリソースには手出し無用です。
そして、アンマネージリソースのみを処分するのが、Dispose(false) というメソッド呼び出しとなります。


> それとも誰かがDisposeを呼んでくれるのか・・・は
期待通りに、誰かに IDisposable.Dispose を呼んでもらえた場合には、Dispose(true) を実行して、
マネージリソースとアンマネージリソースの両方を処分するようにします。
この場合、使用していた資源はすべて処分済みとなりますので、さらに GC.SuppressFinalize に自分を渡し、
ファイナライズが不要であることを伝えるようにします。
引用返信 編集キー/
■35740 / inTopicNo.38)  Re[7]: disposeすべきobjectの判断は?
□投稿者/ 渋木宏明(ひどり) (1148回)-(2009/05/13(Wed) 10:06:17)
渋木宏明(ひどり) さんの Web サイト
> Dispose されなかった場合に備える必要がある場合には、保険としてファイナライザを実装し、

アンマネージリソースをカプセルしていて、IDisposable インターフェースを実装しているなら、「常に」備えるべきです。(例外はまずあり得ない)

ヘルプで解説されていてる「Disposable パターン」では、最基底となるクラスにその「備え」が実装されています。

引用返信 編集キー/
■35798 / inTopicNo.39)  Re[8]: disposeすべきobjectの判断は?
□投稿者/ hirosi (16回)-(2009/05/14(Thu) 01:21:01)
No35726 (渋木宏明(ひどり) さん) に返信
> ヘルプとか読んで、ちゃんとお勉強しましょう。
>
> 明示的なインターフェイスの実装 (C# プログラミング ガイド)
> http://msdn.microsoft.com/ja-jp/library/ms173157(VS.80).aspx
すみません。やっと理解できました。
複数のインターフェイスを実装すると同じメソッド名がかぶってしまったりする事もあるんですね。
IDisposable以外のインターフェイスを使ったことが無かったので気づきませんでした(;^_^A アセアセ・・・
(abstractのクラスを継承するのはよく使うのですが)


No35729 (魔界の仮面弁士 さん) に返信
> # うまく説明できる自信は無いけれども…。
わかりやすく丁寧に説明していただき本当に感謝ですm(__)m

> >>こういうページもあります。
> >>http://msdn.microsoft.com/ja-jp/library/fs2xkftw.aspx
> このあたりも。
> http://msdn.microsoft.com/ja-jp/library/s9bwddyx.aspx
> http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx
新しく紹介していただいた説明を読んでやっと理解できたような気がします。
マネージリソースとアンマネージリソース両方を保有している場合のサンプルもありわかりやすかったです。

長い間お付き合いいただきましてありがとうございました。m(__)m
いろいろと勉強になりました。

これからまたツリーを再度読み直します。
解決済み
引用返信 編集キー/

<前の20件
トピック内ページ移動 / << 0 | 1 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -