いいえ、表示されるコードでは、メモリリークが発生しません。オブジェクトがガベージコレクションされないことを示すためにこの用語を使用することを前提としています。匿名イベントハンドラの代理人は、範囲外になったDataTable
によって作成された残りのオブジェクトでガベージコレクションを長く取得する参照です。私はあなたのコードが何をしているかをシミュレートするために、以下のテスト・リグを作成しました
:
static object DataSource;
static void Main(string[] args)
{
Test1();
// clean up
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
GC.WaitForPendingFinalizers();
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
}
static void Test1()
{
for (var i = 0; i < 1000; i++)
{
var dt = FetchChildren(i);
DataSource = dt.DefaultView;
dt.RowDeleted += (s, e) =>
{
var table = (DataTable)s;
Trace.WriteLine(String.Format("{0}:{1}:{2}", e.Action, e.Row.RowState, table));
};
// do work
var dv = (DataView)DataSource;
dv.Delete(5);
}
DataSource = null;
}
// create a useful datatable
static DataTable FetchChildren(int parent)
{
var dt = new DataTable();
dt.Columns.Add("key", typeof(int));
dt.Columns.Add("guid", typeof(string));
for(var i=0; i<10; i++)
{
var row = dt.NewRow();
row[0] = parent;
row[1] = Guid.NewGuid().ToString("N");
dt.Rows.Add(row);
}
return dt;
}
私はInstrumentaionモードでのVisual Studioでのパフォーマンスエクスプローラでと収集でこれを実行すると。あなたはすべてのDataTableのインスタンスを見ることができるように
:ネットオブジェクトの寿命情報が、これは私の結果であり、有効プロファイリングが終了すると0に戻ります。これは、そのテストでインスタンス化されたすべてのタイプに適用されます。あなたは、インスタンスへの周りの参照を保持しないように、限り
static void Test2()
{
for (var i = 0; i < 1000; i++)
{
var dt = FetchChildren(i);
var local = DataSource; // our previous DataTable
dt.RowDeleted += (s, e) =>
{
var table = (DataTable)s;
Trace.WriteLine(String.Format("{0}:{1}:{2}", e.Action, e.Row.RowState, local)); // use it here
};
DataSource = dt.DefaultView;
// do work
var dv = (DataView)DataSource;
dv.Delete(5);
}
//DataSource = null; // don't dereference
}
:このテストケースのように、あなたがメソッドの最後に1000のインスタンスで終わることができますしかし、周りの参照を保持する場合
以前はあなたは大丈夫でしょう。
パフォーマンス・エクスプローラーに関する有益な情報をありがとう – Tim