Dispose() の呼び出しと、オブジェクトがスコープ/メソッドの外に出るときの比較
-
11-09-2019 - |
質問
私にはメソッドがあります。 try/catch/finaly
中のブロック。try ブロック内で次のように宣言します。 SqlDataReader
次のように:
SqlDataReader aReader = null;
aReader = aCommand.ExecuteReader();
の中に finally
ブロックの場合、手動で破棄されるオブジェクトはクラス レベルで設定されたオブジェクトです。したがって、実装するメソッド内のオブジェクトは IDisposable
, 、 のような SqlDataReader
上記の場合、自動的に処分されるのでしょうか? Close()
呼び出されます aReader
しばらくすると、ループが実行されてリーダーのコンテンツが取得されます (これは Dispose()
それが呼ぶように Close()
)。電話が無い場合は Close()
, 、メソッドが終了するか、オブジェクトがスコープ外になると、このオブジェクトは自動的に閉じられたり破棄されますか?
編集:私はそれを承知しています using
ステートメントですが、私を混乱させるシナリオがあります。
解決
いいえ、オブジェクトはスコープ外に出ても自動的に破棄されません。
ガベージ コレクションされた場合に破棄されるという保証もありませんが、多くの場合、 IDisposable
オブジェクトは、最終的に確実に破棄されるようにするために、「フォールバック」ファイナライザーを実装しています。
あなたには、次のことを保証する責任があります。 IDisposable
オブジェクトは、できればオブジェクトをラップすることによって破棄されます。 using
ブロック。
他のヒント
using {...}
方法を切っ渡し)Dispose()
方法ブロック端を使用するときに呼び出されます - あなたはあなたの中にIDisposableをオブジェクトをラップするClose()
ブロックを使用する必要があります。それは1を持っている場合には、オブジェクトのファイナライザまでとなり、それがあるときに、リソースを取り除くために - あなたはusing
を使用しない場合、それはスコープの外に出るとき、オブジェクトは、のないのは自動的に配置されますごみ収集
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// ... do stuff
} // aReader.Dispose() called here
のDisposeパターンがどのオブジェクトについていかなる保証は、他のどのオブジェクトでのDisposeを呼び出すことはありません。それは時々起こるかもしれませんが、気にしてはいけません。代わりに、それは必ず処分を作るためにあなたの責任だ()すべてのIDisposableをオブジェクトに対して呼び出されます。それを行うための最善の方法は、using
文です。たとえばます:
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// your code
}
私は、上記のすべてに同意します。あなたがあなた自身をDispose()
呼び出すことを確認する必要があり、これまでに最も簡単な方法は、using
文である(あなたもfinally
ブロックでこれを自分で行うことができます - これは、より詳細な、時には必要です)。これを行わない場合は、いくつかのCOMコンポーネントが使用されている、または呼び出しがWin32 APIのに行われている特にどこかに、このすべての下にあれば、あなたのようにハンドルなどのアンマネージリソースをリークするアプリケーション、あるいはアンマネージメモリを見つけることができます。これは明らかに、パフォーマンスと安定性の問題だけでなく、過度のリソース使用率につながることができます。
IDisposable
を実装するオブジェクトは、アンマネージリソースを解放するために彼らのDispose(bool disposing)
メソッドを呼び出すfinaliserを実装する「必要がある」という理由だけで、この現象が発生するという保証はありませんので、あなたは間違いなくそれに頼るべきではありません。例えば、参照、 http://msdn.microsoft .COM / EN-US /ライブラリ/ b1yfkh5e%28VS.71%29.aspx のこの点についての詳細な情報についてます。
また、他の何かが心に留めて、あなたのタイプは使い捨てであるメンバーを持っている場合(これらの部材のライフサイクルが明らかに厄介かもしれない別のタイプによって管理されていない限り)、あなたのタイプはIDisposable
を実装する必要がありますどちらかということである、またはあなたが1つの方法だけでは、このようなメンバーを使用し、または、特定の機能を実装する場合は、あなたがそれらにそれらを使用する方法でローカル変数/パラメータをすることを検討する必要があります。
私は声明で困惑しています「finallyブロックでは、手動で配置されているオブジェクトは、クラスレベルで設定されているものです。」クラスレベルで設定されたオブジェクトによって、あなたはフィールドを意味するのですか?その後、フィールドの寿命が予測不可能である、とあなたが求めているために起こっている方法によって異なりますので、あなたはおそらく、通常のメソッド内でこれらを廃棄すべきではありません。 IDisposableインターを実装し、あなたのDisposeメソッドでフィールドを処分する方が良いでしょう。
文ヘルプをを使用している可能性があり?