弱いイベントに関するMSDNチュートリアルを参照していました。基本を理解しました。私は非WPFプロジェクトに取り組んでおり、クラスは特定のイベントを公開しています。私の質問は、弱いイベントが古いイベントパターンを完全に置き換えるのかということです。イベントを公開しているすべてのクラスで使用するのは良いことですか?弱いイベントを自由に使用することの副作用は何ですか?
4 に答える
私が行った読書に基づいて、WeakEvents を使用することに特定のマイナス面があるようには見えませんが、そうするとより冗長になるという事実を除きます。さらに、ほとんどの場合、イベントが不要になったときに手動で登録を解除できるはずです。場合によっては、これは不可能です。たとえば、参照している MSDN ページでは、WeakEvents を使用する必要がある場合について言及しています。
http://msdn.microsoft.com/en-us/library/aa970850.aspx
特定のシナリオは、本質的に弱いイベント パターンの適用に適しています。そのようなシナリオの 1 つがデータ バインディングです。データ バインディングでは、ソース オブジェクトが、バインディングのターゲットであるリスナー オブジェクトから完全に独立していることが一般的です。WPF データ バインディングの多くの側面には、イベントの実装方法に弱いイベント パターンが既に適用されています。
彼らにどんな種類のネガティブなことも提示したのは、このブログだけです。
一般に、弱いイベントリスナーを使用することにはいくつかの欠点があります。
- 表記が醜い。「元の」.NET の方が見栄えが良い
- イベントに文字列で名前を付ける必要がありますが、これは面倒です (もっと良い方法を知っている場合は、私に連絡してください!)
- EventHandler のハンドラーでのみイベントを処理できます
- あなたはサブスクリプションを気にしない怠惰な開発者になります
基本的に、それらは、オブジェクトが存在している間ずっとサブスクライブするイベントに使用し、オブジェクトが破棄されたときにのみ切断する必要があります。それ以外の場合は、従来のイベントを使用し、イベントを手動で登録/登録解除することをお勧めします。
弱いイベントについては、次の 2 つの問題を考慮する必要があります。
- 弱いイベントを使用すると、サブスクライバーは、イベントを発生させたクラスの ID を知らなくても、イベント (メッセージ) をサブスクライブできます。場合によっては、それが必要でさえあるかもしれません。ただし、場合によっては、不必要に複雑になり、実行時のコードの管理や制御が難しくなるレベルの間接性が生じる可能性があります。
- 弱いイベントを使用することの主な欠点は、開発者がイベント (メッセージ) のサブスクライブを解除する部分を無視する可能性があることです。その場合、サブスクライバーが「範囲外」になった後でも、イベント ハンドラーが呼び出される可能性があります。サブスクライブを明示的に解除せず、ガベージ コレクション可能になるが、まだガベージ コレクションされていないサブスクライバーを考えてみましょう。弱いイベント マネージャーはその状態を検出できないため、そのサブスクライバーのイベント ハンドラーを呼び出します。これにより、あらゆる種類の予期しない副作用が発生する可能性があります。
詳細については、The Weak Event Pattern is Dangerousを参照してください。MvvMCross メッセージング プラグインを弱いイベント マネージャーとして使用して、この問題を説明するこのソース コード
を
参照してください。
弱いイベントをいつ使用するか?
MSDNから
イベントをリッスンすると、メモリ リークが発生する可能性があります
したがって、これらのリークを回避する目的で弱いイベントを使用する必要があります
イベントを公開しているすべてのクラスを使用するのは良いことですか? 弱いイベントを自由に使用することの副作用は何ですか?
C# でのイベントの実装がデフォルトで弱いイベント パターンを使用しないのはなぜですか? を参照してください。. 「強い」イベントからのリークはそれほど一般的ではありません。弱いイベントにはパフォーマンス コストが伴い、すべてのコンテキストで望ましくない意味の違いがある可能性があります。弱い参照の誤用により、イベントが断続的に発生しなくなる可能性があります (メモリ リークを引き起こす通常のイベントの誤用)
回避できるメモリリークの例
静的クラスとシングルトンは、メモリリークについて話すときの悪役です。他のオブジェクトへの参照を取得すると、オブジェクトがガベージコレクションされるのを防ぎ、アプリケーションの寿命のためにオブジェクトをリークします。ここに私が会った例がありますメモリリークを避けるために弱参照が必要