2009-06-30 25 views
53

イベントハンドラが少数しか登録されていないアプリケーションがあると(アプリケーションを閉じるまでイベントを使用しているオブジェクトが破棄されない)、本当にハンドラの登録を解除する必要がありますか?私が見ることができる唯一の良い理由は、イベントが発生したときに、必要以上に気にかけていない(つまり、1つのイベントに複数のハンドラを登録している)場合に少しオーバーヘッドが発生する可能性があるということです。その他の理由がありますか?彼らはイベントの登録を解除したので誰もが大きな問題に遭遇しましたか?あなたはAイベントを公開し、Bはイベント(ハンドラ)に加入している場合イベントハンドラの登録を解除しないと悪いですか?

答えて

68

は、ABより多く長生きしようとしている場合は解除しない唯一の問題です。基本的に、イベントサブスクリプションとは、AがまだBを見ることができるので、ガベージコレクションができないようにし、それを忘れてもイベントを発生させます(おそらくDisposed())。

たとえば、これが問題であるAが静的​​なイベントであり、そしてBが死んだ後にアプリをしばらく走る...

場合、1つが以下のように頼むかもしれない、注意することが重要です

もしBがAよりも長く生き残っているならば、BはAをガベージコレクトしないようにしますか?

そしてその答えは「いいえ」です。 Bはイベントを通じてAへの参照を持たない。 Aは通常通り収集されます

+0

Bがリソースの重い場合は、特に悪いです... –

+0

Marc。静的イベントのハンドラは、サブスクライバを廃棄するときに注意を払わなければ、本当に悪名高いものです。 – TheVillageIdiot

+3

これは古い投稿ですが、読まれるかどうかわかりませんが、BがAよりも長く生きれば、BはAをガベージコレクションから守るでしょうか? @Scott。 –

14

多くの人々は、出版社が加入者を失うことになるとイベントから退会することが重要であると考えているようです。私はそのアプローチを嫌いです。パブリッシャから切り離されないイベントサブスクライバは、パブリッシャとサブスクライバの外部のエンティティの動作にいくつかの厄介な依存関係を作成します。パブリッシャへの参照が予想より長く保持されていると、サブスクライバが参照を保持しているオブジェクトとともに、サブスクライバが有効になります。放棄されたオブジェクトの大部分がイベントハンドラによって相互接続されていて、いずれかのライブ参照が存在しない場合、すべてのオブジェクトはガベージコレクタによって掃除されます。しかし、誰かが予期せずにオブジェクトの1つへの参照を保持していると、そのオブジェクトがガベージコレクションされない可能性があります。

IMHO、イベントハンドラを削除することは、イベントハンドラを放棄するよりも予防​​的で、すべてがクリーンアップされることを期待する方がはるかに優れています。パブリッシャへの予期せぬ参照が存在しないことが確実である場合を除き、このようなアプローチは「主に」動作する可能性がありますが、時々メモリリークが発生します。

関連する問題