私の.netサービスは、Main()ループが終了する前にfinallyブロックでresourceName.Dispose()を呼び出すことにより、管理されていないすべてのリソースをクリーンアップします。
私は本当にこれをしなければなりませんか?
プロセスが終了しているため、リソースをリークできないと考えるのは正しいですか?Windowsは、使用されなくなったハンドルをすべて閉じますよね?
私の.netサービスは、Main()ループが終了する前にfinallyブロックでresourceName.Dispose()を呼び出すことにより、管理されていないすべてのリソースをクリーンアップします。
私は本当にこれをしなければなりませんか?
プロセスが終了しているため、リソースをリークできないと考えるのは正しいですか?Windowsは、使用されなくなったハンドルをすべて閉じますよね?
その特定のケースでは、これをスキップしてもおそらく問題ありません。
最初に理解しておくべきことは、プロセスを終了するだけでほとんどのものをクリーンアップできるはずですが、一部の管理されていないリソースが不良または閉じられていない状態のままになる可能性があるということです。たとえば、シートごとにライセンスが付与されているアプリがあり、アプリが閉じたときに、ライセンスを解放するためにどこかでデータベースレコードを更新する必要があるとします。プロセスが正しく終了しない場合、その更新は何も起こらず、ソフトウェアから人々を締め出すことになりかねません。プロセスが終了したからといって、クリーンアップを行わない言い訳にはなりません。
ただし、IDisposableパターンを使用する.Netの世界では、もう少し保険に加入できます。プロセスが終了すると、残りのすべてのファイナライザーが実行されます。Dispose()パターンが適切に実装されている場合(そしてそれが本来あるべきよりも大きな「if」である場合)、ファイナライザーはオブジェクトの残りの管理されていないリソースを処理するためにそこにあります...
ただし、これらのものを自分で正しく処分する習慣を常に身に付けることをお勧めします。また、FWIWでは、.Dispose()を呼び出すだけでは、これを正しく行うには不十分です。.Dispose()呼び出しは、finallyブロック(ステートメントで取得する暗黙のfinallyブロックを含む)の一部として含める必要があります。using
を実装するオブジェクトによってカプセル化できるリソースのタイプに制限はありませんIDisposable
。オブジェクトによってカプセル化されたリソースの大部分はIDisposable
、プロセスがシャットダウンしたときにオペレーティングシステムによってクリーンアップされますが、一部のプログラムは、オペレーティングシステムが何も知らないリソースを使用する場合があります。たとえば、基盤となるデータベースでサポートされていないロックパターンを必要とするデータベースアプリケーションは、1つ以上のテーブルを使用して、何が誰によって「チェックアウト」されているかを追跡する場合があります。そのようなテーブルを使用してリソースを「チェックアウト」するクラスは、Dispose
すべてがチェックインされるメソッドですが、クラスがテーブルをクリーンアップする機会がないままプログラムがシャットダウンすると、そのテーブルによって保護されているリソースがぶら下がったままになります。オペレーティングシステムには、これらのテーブルの意味がわからないため、それらをクリーンアップする方法がありません。