コード レビュー中に、使用するすべてのクエリ オブジェクト (LinqToEntities) に対して dispose メソッドを実行するように言われました。
これはそんなに大きなメモリリークですか?これをよりエレガントに修正するにはどうすればよいですか?
私のコードは次のとおりです。
var query = from x in listOfEntities where some_condition select x;
コード レビュー中に、使用するすべてのクエリ オブジェクト (LinqToEntities) に対して dispose メソッドを実行するように言われました。
これはそんなに大きなメモリリークですか?これをよりエレガントに修正するにはどうすればよいですか?
私のコードは次のとおりです。
var query = from x in listOfEntities where some_condition select x;
このクエリはメモリリークを引き起こさないと思います。問題を引き起こす可能性のあるクエリではありません。おそらくデータコンテキストです。データ コンテキストは IDisposable を実装しているため、次のことができます。
using (var ctx = new yourDataContext())
{
var query = from x in ctx.listOfEntities where some_condition select x;
}
withusing
句を使用すると、コードが using ステートメントを終了した後、データベースへの接続が確実に閉じられます。try/finally ブロックに似ています。
var ctx = new yourDataContext();
try
{
var query = from x in ctx.listOfEntities where some_condition select x;
}
finally
{
if(ctx != null)
ctx.Dispose();
}
編集:(@Fredrik Mörk からのコメントに基づく)。上記のコードは、using
に関するステートメントの使用法を示すためのものDataContext
です。using ブロックの外側でオブジェクトを使用するには、query
ブロックの外側でオブジェクトを定義し、または同様のメソッドusing
を呼び出しToList
て、クエリを実行できるようにします。後で使用できます。そうしないと、遅延実行により、現在のコード ブロックが失敗します。
この状況に固有のものではありませんが、呼び出しの欠如がDispose
リークを引き起こすかどうかは、破棄可能なオブジェクトの内部の仕組みに依存します。フレームワークには、破棄時にほとんどまたは何もしない破棄可能なオブジェクトの例があります。一部の実装では、最終的に GC によって処理されるマネージド オブジェクトのみを処理します (したがって、この場合、オブジェクトの確定的な破棄のみが失われ、必ずしもメモリ リークが発生するわけではありません)。
契約の重要な部分は、IDisposable
それがテーブルにもたらす慣習です。内部の仕組みは変更可能であり、契約は変更可能ではないため、内部の仕組みに関係なく契約を順守します。私はやみくもにルールを適用するのは好きではありませんが、使用しているアイテムを常に処分しようとする傾向があります。