- PR -

Disposeはどう書くべき?

1
投稿者投稿内容
YAMANEKO
会議室デビュー日: 2008/06/06
投稿数: 19
投稿日時: 2008-06-30 11:45
アンマネージドリソース(COMポート)を扱うライブラリを作っていて、
少々迷っているのですが・・・
結局のところ、Dispose()の正しい書き方って、どうなのでしょうか??

MSDNによれば・・・
http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx

IDisposableのDisposeの実装から、Dispose(bool)を呼び出す・・・というような
作りになっていますが、
Dispose(bool)のif(disposing)の中でやることになっている、
マネージドリソースの開放、というのがわかりません。
そんなの必要あるのでしょうか?というか、
そもそも、どうやって開放するのでしょうか??
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2008-06-30 12:09
大雑把には、メンバのうち IDisposable なものに対して Dispose を呼び出せって事ですね。
不要なものに関してはついでに null を代入することもありますが大抵の場合あまり意味は無いです。
YAMANEKO
会議室デビュー日: 2008/06/06
投稿数: 19
投稿日時: 2008-06-30 12:37
引用:

Hongliangさんの書き込み (2008-06-30 12:09) より:
大雑把には、メンバのうち IDisposable なものに対して Dispose を呼び出せって事ですね。
不要なものに関してはついでに null を代入することもありますが大抵の場合あまり意味は無いです。



MSDNの他のアーティクルを読むと、さらに混迷を深めます。。

「GC.SuppressFinalize を正しく呼び出します」
http://msdn.microsoft.com/ja-jp/library/ms182269.aspx

ここでは、Dispose(bool)の引数が真のときだけ、アンマネージドリソースの開放をしていますが、

「アンマネージ リソースをクリーンアップするための Finalize および Dispose の実装」
http://msdn.microsoft.com/ja-jp/library/b1yfkh5e.aspx

ここでは、デストラクタから、Dispose(false)を呼ぶことになっています。
そうすると、Disposeを呼ばずにデストラクタが呼ばれたときは、
マネージドリソースは開放しない??
そもそも、Disposeに引数を付けて、開放処理を分けている理由はなんなのでしょう。。?
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2008-06-30 13:18
引用:

「GC.SuppressFinalize を正しく呼び出します」
http://msdn.microsoft.com/ja-jp/library/ms182269.aspx
ここでは、Dispose(bool)の引数が真のときだけ、アンマネージドリソースの開放をしていますが、


マネージリソースの解放、です。それは(繰り返しになりますが)大雑把に言えば Dispose の呼び出しです。
アンマネージリソースの解放ってのは CloseHandle の呼び出しとかそんなんです。解放対象は一般に IntPtr 型をしています。

引用:

ここでは、デストラクタから、Dispose(false)を呼ぶことになっています。
そうすると、Disposeを呼ばずにデストラクタが呼ばれたときは、
マネージドリソースは開放しない??
そもそも、Disposeに引数を付けて、開放処理を分けている理由はなんなのでしょう。。?


// 「デストラクタ」は構文の名前に過ぎず、機能を呼ぶときは「ファイナライザ」と呼ぶようにしましょう。C++ のデストラクタとごっちゃになっちゃまずいので。
どのみちアンマネージリソースの解放は必要なので一つにまとめるんです。もちろん、アンマネージリソースを持っていないならファイナライザは必要ありません。
ファイナライザが呼び出されるときは、自分の持つフィールドが先に解放されている可能性があります。そのためファイナライザでは自分のフィールド(のうち参照型のもの)は触れないと言っていいです。当然、マネージリソースは解放できません。普通はそれらもそれら自身のファイナライザで自らが持つアンマネージリソースを解放します。
また protected virtual Dispose(bool) パターンを遵守することで、IDisposable なクラスを派生させたときにこれを override すればいいと明らかであるのも利点です。
YAMANEKO
会議室デビュー日: 2008/06/06
投稿数: 19
投稿日時: 2008-06-30 14:05
引用:

Hongliangさんの書き込み (2008-06-30 13:18) より:
どのみちアンマネージリソースの解放は必要なので一つにまとめるんです。もちろん、アンマネージリソースを持っていないならファイナライザは必要ありません。
ファイナライザが呼び出されるときは、自分の持つフィールドが先に解放されている可能性があります。そのためファイナライザでは自分のフィールド(のうち参照型のもの)は触れないと言っていいです。当然、マネージリソースは解放できません。普通はそれらもそれら自身のファイナライザで自らが持つアンマネージリソースを解放します。



なるほど、
アンマネージドリソースと、それをカプセル化したマネージドリソースの違いが、
ごっちゃになっていたのが誤解の原因でした
ファイナライザが呼ばれたときは、すでに、自分のフィールドのマネージドリソースには触れなくなっている可能性があるから、
Disposeに引数を付けて処理を切り分けているのですね。
理解できました。ありがとうございました!
1

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