TextBox などの WPF コントロールを派生させ、OnInitialized などの On- メソッドの 1 つをオーバーライドするとします。
私がこれをしたとします:this.Initialized += delegate { };
このコントロールを含むウィンドウが閉じられた場合 - 他に何もしないとメモリ リークが発生しますか?
これによりメモリ リークが発生する場合、Finalizer を実装するだけで十分で最小限の解決策になりますか?
あなたが考えているメモリリークは、イベントハンドラーをオブジェクトのイベントにアタッチし(「A」と呼びます)、ハンドラーを所有するオブジェクト(「B」)へのすべての参照を失うことです。ガベージ コレクタは、オブジェクト「A」のイベントを通じてオブジェクト「B」に到達できるため、オブジェクトを収集することはありません。詳細については、この質問を参照してください。
あなたの場合、Form
. がForm
閉じられ、それへのすべての参照を削除すると、コードの残りの部分からフォームにアクセスする方法がないため、GC は喜んでそれを収集します (フォームに到達したとき)。漏れは発生しません。
最後のコメントに基づいて、ファイナライザーの実装は、あなたが思っていることをしないかもしれません。これは、クリーンアップ コードを実行するためにランタイムが提供する単なるフックであり、IDisposable
interface と patternを実装することをお勧めします。イベントを公開するクラスでよく行うことの 1 つは、メソッドでイベントを null に設定するDispose
ことです。すなわち:
class Foo : IDisposable
{
public event EventHandler SomethingHappened;
// ... normal IDisposable implementation details left out
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
SomethingHappened = null;
}
}
}
すべてのクラスでこれを行っているわけではありませんが、オブジェクトがなくなるときにすべてのハンドラーをオブジェクトから削除する比較的クリーンな方法です。これは、クラス自体の内部からのみ行うことができます。
いずれにせよ、イベントにForm
基づいて作業を行うPreviewMouseLeftButtonDown
場合は、代わりにメソッドをオーバーライドする必要がありますOnPreviewMouseLeftButtonDown
。クラス自身のイベントをリッスンするためにイベント ハンドラーをアタッチすることは、一般的に不適切な形式です。代わりに次の操作を行います。
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
// Actually raise the event to let other classes know it happened
base.OnPreviewMouseLeftButtonDown(e);
// your code...
}