60


16

少数のイベントハンドラしか登録されていないアプリケーションがある場合(そしてイベントを使用しているオブジェクトはアプリケーションが閉じられるまで破棄されない場合)、それらのハンドラの登録を解除することを本当に心配する必要がありますか? 私が知ることができる唯一の正当な理由は、あなたが必ずしも気にしないイベントが発生している場合、少し余分なオーバーヘッドがあるかもしれないということです(すなわち、あなたは複数のハンドラが一つのイベントに登録されています)。 他に何か正当な理由がありますか? 誰もがイベントの登録を抹消しなかったので、大きな問題に遭遇しますか?

2 Answer


78


イベントを公開している `+ A `と、イベント(ハンドラー)をサブスクライブしている ` B `がある場合、 ` A `が ` B + `。 基本的に、イベントサブスクリプションとは、 `+ A `がまだ ` B `を見ることができるため、ガベージコレクションされないようにし、忘れた場合でもイベントを発生させます(そしておそらく Disposed( )+ `it)。

たとえば、これは、「+ A 」が静的イベントであり、「 B 」が死んだ後しばらくアプリが実行される場合に問題になります... しかし、 ` B `は ` A `が存続する限り存続します。したがって、 ` B +`はガベージコレクションされません。

注意することは重要です、人は以下を尋ねるかもしれません:

_ BがAよりも長生きする場合、BはAがガベージコレクションされないようにしますか? _

そしてそれに対する答えは「いいえ」です。 Bは、イベントを通じてAを参照しません。 Aは通常どおり収集されます


14


パブリッシャーが購読者よりも長生きするのであれば、イベントから購読を中止することが重要だと考える人は多いようです。 私はそのアプローチが嫌いです。 パブリッシャから自分自身をデタッチしないイベントサブスクライバは、パブリッシャとサブスクライバ以外のエンティティの動作に厄介な依存関係を作成します。 パブリッシャへの参照が予想よりも長く保持されている場合、それは、購読者が参照を保持しているすべてのオブジェクトとともに、購読者を生存させます。 大量の放棄されたオブジェクトがイベントハンドラによって相互接続されていても、それらへのライブ参照が存在しない場合、すべてのオブジェクトはガベージコレクタによって一掃される可能性があります。 しかし、どこかの人が予期せずにオブジェクトの1つへの参照を保持していると、それらのいずれもがガベージコレクションされるのを妨げる可能性があります。

私見、イベントハンドラを捨てるよりも積極的にイベントハンドラを削除した方が良いでしょう。 出版社への予期しない参照が存在し得ないことが確実でない限り、そのようなアプローチは「ほとんど」動作する可能性がありますが、時折メモリリークを引き起こします。