Memory Management
以下のようなデータを返しながらwhileを使用しています。
private DataSet ReturnDs()
{
using (DataSet ds = new DataSet())
{
return ds;
}
}
クエリ-データを返すときに「Using」ステートメントを配置することに問題はありますか?受信関数のデータだけでなく、完全なスキーマをまだ取得していますか?
これは間違いなく間違ったパターンです。それが今あなたのために働いている唯一の理由は、それDataSet.Dispose()
が実際にはダミーであるということです。
using (DataSet ds = new DataSet())
{
return ds;
} // there is a ds.Dispose() here but it does nothing.
DataSetをたとえばEnitityフレームワークのDbContextに置き換えると、呼び出し元の関数にデータが表示されなくなります。
一般的に、返そうとしているオブジェクトを破棄することはエラーです。コードはそのオブジェクトで終了しておらず、壊れたオブジェクトを呼び出し元に渡します。
つまり、そうしないでください。つまり、返すオブジェクトでDispose()
使用しないでください。using
それを処分するのは発信者次第です:彼らは今所有者です。もちろん、これは理想的にはAPIで文書化する必要があります。
ただし、より一般的には、例外についても考慮する必要があります。メソッドエラーが発生した場合はどうなりますか?複雑なシナリオでは、次のようなものが必要になる場合があります。
SomeType foo = null;
try {
// initialize and populate foo - this could error half-way through
return foo;
} catch {
if(foo != null) foo.Dispose();
throw;
}
障害が発生した場合にオブジェクトが正しく配置されるようにします。
using
オブジェクトを返すメソッドではなく、呼び出し元のメソッドでステートメントを使用します。
public void Caller()
{
using(DataSet ds = GetDataSet())
{
// code here
}
}
public DataSet GetDataSet()
{
// don't use a using statement here
return ds;
}
ステートメントは基本的にこれusing
を行うのと同じです:
DataSet ds = null;
try
{
// code here
}
finally
{
if(ds != null)
{
ds.Dispose();
ds = null;
}
}
したがって、using
ステートメント内のオブジェクトを返すことになっているメソッドでステートメントを使用するusing
と、Disposedオブジェクト(つまり、閉じたストリーム、閉じたデータセットなど)が返されます。これは、内部オブジェクトの一部がnullになる可能性があることを意味します。 、または閉じています。つまり、最初にIDisposableを実装する目的で、すべての内部リソースがクリーンアップされます。アプリケーションがこれらの内部リソースの一部を利用可能にすることに依存している場合、たとえばStreamオブジェクトを使用している場合、例外がスローされます。
また、すべてのfinally
ブロックが同じように記述されているわけではないことにも注意してください。IDispoableは、内部リソースとアンマネージドオブジェクトをクリーンアップするために実装されたことを忘れないでください。これらの内部リソースはステートメントの外部では必要ない場合があるusing
ため、ステートメントをそのまま使用using
すると正しく機能するように見える場合がありますが、推奨されておらず、すべてのオブジェクトで確実に機能するとは限りません。Microsoftが将来のリリースでDataSetオブジェクトを変更し、アプリケーションに不可欠なものを破棄することを決定した場合、動作中のコードは突然動作を停止します。
あなたの質問が正確に何であるかわかりません。
メソッドが何かを再調整して終了すると、ds.Dispose()
が自動的に呼び出されます。
これは、メソッドが返すDataSetは、呼び出し元のメソッドがそれを受け取ったときにすでに破棄されていることを意味します。
Mertのコメントとして、返されるオブジェクトを破棄していることに注意してください。ただし、基本的に、使用は実際にはtry / finalであり、disposeはメソッドreturnと呼ばれます。効果は、各タイプのIDisposable実装によって異なります。通常、呼び出し元に返すエンティティを破棄(強制終了)して、おそらくそれを使用することは想定されていません。