IDisposableの目的は何ですか?
-
03-07-2019 - |
質問
.NETにガベージコレクションがある場合、なぜ IDisposable
を明示的に呼び出す必要があるのですか?
解決
ガベージコレクションはメモリ用です。メモリ以外のリソース(ファイルハンドル、ソケット、GDI +ハンドル、データベース接続など)を破棄する必要があります。これは通常、 IDisposable
タイプの根底にありますが、実際のハンドルはチェーンのかなり下にある可能性があります参照の。たとえば、 FileWriter
を破棄する StreamWriter
を参照する XmlWriter
を破棄する Dispose
it への参照があり、ファイルハンドル自体を解放します。
他のヒント
他のコメントを少し拡大:
非管理リソースへの参照を持つすべてのオブジェクトでDispose()メソッドを呼び出す必要があります。そのような例には、ファイルストリーム、データベース接続などがあります。ほとんどの場合に機能する基本的なルールは次のとおりです。" .NETオブジェクトがIDisposableを実装する場合、オブジェクトの処理が終了したらDispose()を呼び出す必要があります。
ただし、留意すべきその他の事項:
- disposeを呼び出しても、オブジェクトが実際に破棄され、メモリが解放されるタイミングを制御することはできません。 GCがそれを処理し、できる以上にうまく処理します。
- Disposeは、すべてのネイティブリソースをクリーンアップし、Jonが示したように、基底クラスのスタック全体をクリーンアップします。次に、SuppressFinalize()を呼び出して、オブジェクトを再生する準備ができており、それ以上の作業が不要であることを示します。 GCの次の実行でクリーンアップされます。
- Disposeが呼び出されない場合、GCはオブジェクトをクリーンアップする必要があると判断しますが、リソースが解放されていることを確認するために、まずFinalizeを呼び出す必要があります。Finalizeの要求はキューに入れられ、GCが移動します。 Disposeの呼び出しがないと、オブジェクトをクリーンアップする前にもう1つのGCが実行されます。これにより、オブジェクトは次の「世代」にプロモートされます。 GCの。これは大したことではないように思えるかもしれませんが、メモリが圧迫されるアプリケーションでは、GCのより高い世代までオブジェクトをプロモートすると、メモリの多いアプリケーションがメモリ不足のアプリケーションになります。
-
絶対に必要な場合を除き、独自のオブジェクトにIDisposableを実装しないでください。実装が不十分または不要な実装は、実際には事態を改善する代わりに悪化させる可能性があります。いくつかの良いガイダンスがここにあります:
オブジェクトはメモリの横にリソースを保持することがあるためです。 GCはメモリを解放します。 IDisposableは、他のものをリリースできるようにするためのものです。
オブジェクトによって保持されているリソースがクリーンアップされるタイミングを制御するため。
GCは動作しますが、そのように感じると動作します。その場合でも、オブジェクトに追加したファイナライザーは、GCコレクションが2回収集された後にのみ呼び出されます。時々、それらのオブジェクトをすぐにクリーンアップしたいことがあります。
これは、IDisposableが使用される場合です。 Dispose()を明示的に呼び出す(またはusingブロックのthr
すぐにクリーンアップするリソースの例は、データベースハンドル、ファイルハンドル、ネットワークハンドルです。
usingキーワードを使用するには、オブジェクトにIDisposableを実装する必要があります。 http://msdn.microsoft.com/en-us /library/yh598w02(VS.71).aspx
IDisposable
インターフェースは、多くの場合リソースの観点から説明されますが、そのような説明のほとんどは、実際に「リソース」が何であるかを考慮していません。本当に意味します。
一部のオブジェクトは、他のエンティティに損害を与えるために、さらに通知されるまで、外部エンティティに何かを依頼する必要があります。たとえば、ファイルストリームを含むオブジェクトは、ファイルシステム(接続されたユニバースのどこにある場合もあります)にファイルへの排他的アクセスを許可するように要求する必要がある場合があります。多くの場合、外部エンティティに対するオブジェクトのニーズは、オブジェクトに対する外部コードのニーズに結び付けられます。クライアントコードが前述のファイルストリームオブジェクトで行うことをすべて実行すると、たとえば、そのオブジェクトは、関連付けられたファイルへの排他的アクセス(またはそのためのアクセス)を持つ必要がなくなります。
一般に、追加の通知までエンティティに何かを要求するオブジェクトXは、そのような通知を配信する義務を負いますが、XのクライアントがXのサービスを必要とする限り、そのような通知を配信できません。 IDisposable
の目的は、サービスが不要になることをオブジェクトに通知するための統一された方法を提供することです。これにより、 サービスは不要になりました。 IDisposable
は、義務を果たすためにオブジェクトを招待するだけであるため(
"リソース"の観点から物事を述べるために、オブジェクトは外部のエンティティに何かを行うように依頼するときにリソースを取得します(通常、必ずしもではありませんが、何かの排他的使用を許可します)。外部エンティティのサービスが不要になったことを伝えるときのリソース。リソースを取得するコードは、「もの」を獲得しません。義務を負う限り。リソースを解放しても「もの」は放棄されませんが、代わりに義務を果たします。