問題タブ [weak-events]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
.net - WPFアプリケーションで使用される「ウィークイベント」パターンとは何ですか?
WindowsBase
DLLは、IWeakEventListener
要約を使用してイベントを定義します。
WeakEventパターンとSystem.Windows.WeakEventManagerを介してイベントを受信することを期待するクラスにイベントリスニングサポートを提供します。
この漠然とした説明は、「WeakEventパターン」が実際に何であるかを説明していません。
では、このパターンとは何ですか、なぜそれが使用され、WPFアプリケーションの外部で役立つのでしょうか?
編集すでにいくつかの良い答えがありますが、このパターンがWPFアプリケーションの外部で役立つかどうかについては誰も話していません。依存関係のプロパティのような弱いイベントパターンは、WPFAPIおよびDLLと密接に関連しているように思われます。非WPFアプリケーションで利用できる同等の実装はありますか?
c# - Windows.FormsアプリケーションでのWeakEventManagerの使用
ここで説明されているように弱いイベントを使用する場合http://wekempf.spaces.live.com/blog/cns!D18C3EC06EA971CF!373.entryWindows.FormsアプリケーションでWeakEventManagerがWeakReferenceオブジェクトをリークします。これは、WPFメッセージループがないと、ScheduleCleanupがWeakEventManager.ProtectedAddListenerで呼び出されても、CleanupOperationが実行されないためだと思います。
回避策として、次のようなクリーンアップ関数を実装しました。
たとえば、への16回目の呼び出しごとにこれを呼び出しますProtectedAddListener
。
これは機能しますが、明らかに私はこの(乱用された)反射の使用を避けたいと思っています。
だから私の質問は:
- パブリック/保護されたメンバーを使用してクリーンアップ機能を実装する方法はありますか?WeakEventManager.Purgeは便利かもしれませんが、使い方がわかりません。
- Windows.FormsベースのアプリケーションでWPFメッセージループを実行する簡単な方法はありますか?
.net - .NETのWeakEventManagerを使用したウィークイベントの実装例
.NETのWeakEventManagerを使用した弱いイベントの実装例はありますか?
ドキュメントの「継承者への注意」に従って実装しようとしていますが、あいまいです。たとえば、カスタムマネージャーProtectedAddListener
の静的関数から呼び出す方法がわかりません。AddListener
wpf - WPF コントロールはバインディングで弱いイベントを使用しますか?
WPF でデータ バインディングを使用すると、ターゲット コントロールがバインディング ソースのイベントをリッスンします。たとえば、でイベントをListView
リッスンしている場合があります。CollectionChanged
ObservableCollection
イベント ソースの有効期間がイベント リスナーの有効期間を超えることが予想される場合は、メモリ リークが発生する可能性があるため、弱いイベント パターンを使用する必要があります。
WPF データバインディングは弱いイベントパターンに従いますか? 私の寿命が私のObservableCollection
寿命よりも長い場合、ガベージコレクションの対象になりますか?ListView
ListView
これが、WPF コントロールが弱いイベント パターンを実装していないと私が疑う理由です。DerivedListView Collected!
もしそうなら、私はとの両方DerivedTextBlock Collected!
がコンソールに出力されることを期待します。代わりに、あるだけDerivedTextBlock Collected!
です。
コードのバグを修正した後、両方のオブジェクトが収集されます。どう考えたらいいのかわからない。
Window1.xaml.cs
Window1.xaml
c# - C#言語:なぜWeakReferenceまたはWeakイベントパターンなのか?
WeakReference
私は「TheC#Language」、第4版を読んでいます、それは話しWeak Event Pattern
ます:
CHRISTIAN NAGEL:メモリリークは、イベントの誤った使用に起因することがよくあります。クライアントオブジェクトがイベントにアタッチされているが、イベントから切り離されておらず、クライアントオブジェクトへの参照が使用されなくなった場合でも、パブリッシャーによる参照が残っているため、クライアントオブジェクトをガベージコレクターが再利用することはできません。これは、(1)クライアントオブジェクトが使用されなくなったときにイベントをデタッチする、(2)デリゲートを保持するクラスを使用する、
add
およびremove
アクセサーのカスタム実装、または(3) IWeakEventListenerでWPFによって使用されるイベントによって回避できます。インターフェース。WeakReference
Weak Event pattern
ここで疑問があります。オプション「(2)WeakReference
」は、「オプション(1)イベントの明示的なデタッチ」と比較して、まったく便利ではありません。これは、を使用すると、との両方をWeakReference
明示的に呼び出す必要があるためです。add
remove
そうしないと、イベントハンドラーのオブジェクトの1つがnullに割り当てられた場合でも、「孤立した」オブジェクトはイベントに応答します。これにより、予期しない動作が発生します。
注:WeakReference
イベントハンドラーのオブジェクトがイベントパブリッシャーオブジェクトの影響を受けないようにする方法でのみ、ガベージコレクションを支援します。WeakReference
イベントハンドラオブジェクトにガベージコレクションを強制しません。
同様の問題は、弱いイベントパターンにも当てはまります。
これは少し抽象的かもしれません。例として、Josh Smithのメディエーターパターン(http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/)を取り上げます。
私たちが持っている場合
最後の行は、?のために予期しない動作を引き起こしませんでしたWeakReference
か?
しかし、Mediator
クラスが「登録解除」メソッドを提供する場合(実際に私はそれを実装しました)、「オプション(2)WeakReference
」は「オプション(1)イベントを明示的にデタッチする」と違いはありません。(メディエーター自体は依然として有用なパターンであり、WPFまたはMVVMコンポーネントレイヤーの階層に侵入できます)
events - INotifyPropertyChanged の放棄可能なユーザーのための安全で漏れのないパターンはありますか?
INotifyPropertyChanged のコンシューマーが、特定の INotifyPropertyChanged オブジェクトの有効期間中にコンシューマーの任意の数のインスタンスが作成される可能性がある状況でも、そのオブジェクトのプロパティが変更されずにメモリ リークを回避できるパターンはありますか?通知の発火)?イベント パブリッシャーがリフレクションの策略を使って弱いイベントを実装することは可能です。実行可能なサブスクライバー側の弱いイベント パターンはありますか?
イベント コントラクトで、イベント サブスクライバーが無期限にブロックすることなく、いつでも任意のスレッドからサブスクライブ解除できるようにする必要がある場合、イベント サブスクライバーは、サブスクライバーに実際に「関心のある」オブジェクトを保持することができます。ラッパー オブジェクトへの参照を作成し、ラッパー オブジェクトで Finalize() をオーバーライドして、サブスクライバー オブジェクトにサブスクライブを解除するように指示します。残念ながら、サブスクライバーが Finalize() を介してサブスクリプションをキャンセルする必要があることを発見した場合でも、.net イベント コントラクトでは、イベントを発行するオブジェクトをファイナライザー内から安全に破棄できるようにする必要はありません。実際、C# の既定のイベント実装は、ファイナライザー内から呼び出すのは安全ではありません (現在の実装は、サブスクリプションを発行するオブジェクトのロックを取得します。ロックがサブスクリプションとサブスクリプション解除にのみ使用される場合は問題ありませんが、ロックが他の目的で任意の期間保持されないという保証はありません)。以前の実装はもっと悪かった: クラスがそれ自体のイベントを購読または購読解除しようとした場合、購読と購読解除はまったくスレッドセーフではありませんでした。
INotifyPropertyChanged オブジェクトが、そのイベントをスレッド セーフな方法で実装した特定のクラスであることがわかっている場合 (サブスクリプションの場合は、ロックを取得してから Interlocked.Exchange スピン ループを使用します。サブスクリプション解除の場合は、スピン ループを使用して、利用可能な場合はロックしますが、ロックが利用可能かどうかに関係なく Interlocked.CompareExchange を試行します) ファイナライザーでイベント ハンドラーを安全に削除できます。オブジェクトがかなりの頻度でイベントを発生させることがわかっている場合は、おそらくイベント内からハンドラーを削除できます (ただし、.net イベント コントラクトで安全である必要があるかどうかはわかりません)。監視する INotifyPropertyChanged 実装者のタイプに関係なく機能する汎用ソリューションはありますか?
編集 -- 明確化
オブジェクトがそれ自体のファイナライザーからサブスクライブを解除するという考えではなく、イベントの効果に関心のあるオブジェクトが、イベント処理自体が参照を保持しないラッパー オブジェクトへの参照を保持するということです。たとえば、特定のイベント名文字列で PropertyChanged イベントが発生した回数をカウントすることが目標であるとします。PropertyChangeCounter.Internals オブジェクトへの参照を保持する PropertyChangeCounter オブジェクトを持つことができます。後者のオブジェクトは、イベント サブスクリプションと変更カウントを保持します。PropertyChangeCounter オブジェクトの ChangeCount プロパティは、ネストされた PropertyChangeCounter.Internals ChangeCount の値を返します。ラッパーオブジェクトは、部外者がそれへの参照を保持しなくなると、ファイナライズの対象になります。
c# - C# での WeakEvent ガベージ コレクション
今日は次のシナリオで考えています。
私はAとBの2つのクラスを持っています。
A はイベント E を公開します。
B は、弱いイベント ハンドラ「W」を使用して、このイベント「E」をサブスクライブします。
しばらくすると、誰も B への参照を保持していませんが、GC はまだ開始されていません。
B がまだ GC によって収集されておらず、A が "E" を発生させている間に、弱いイベント ハンドラーが呼び出されますか?
はい、と考えていますが、何かが欠けていない場合は好奇心旺盛です。
silverlight - Silverlightの弱いイベントの適切な実装は何ですか?
メモリリークを回避するために、Silverlightの弱いイベントパターンを適切に実装した後です。そこにはいくつかの実装があるようですが、コードは簡単ではなく、どれが正しいかを知るのは難しいです。Microsoftからの公式の推奨事項が見つかりません。
可能であれば、私は単純な構文を求めています。
乾杯。
c# - emddudley の WeakEventManager のサンプル
Michael Dudley のサンプル コードを、弱いイベント マネージャーの独自の実装に適合させようとしています。
.NET の WeakEventManager を使用した弱いイベントの実装例
自分のハンドラーのユーザー コードをどこに配置すればよいのだろうか? 私はこれを見る:
その式の内容を独自のカスタム コードに置き換えますか?
ありがとうございました、
ケビン
c# - 弱いイベントはどのように機能しますか?
私は現在 WPF を学んでおり、弱いイベントの概念に出くわしましたが、「それを理解する」のに本当に苦労しています。私は Stackoverflow に関する数え切れないほどの記事を読み、コード サンプルを見てきましたが、うまく理解できていません。
ここに私のジレンマがあります:
- オブジェクトがイベントをサブスクライブする場合、イベントのソースはサブスクライバーへの参照を保持する必要があることを理解しています。
- また、サブスクライバーがスコープ外になるか、明示的に破棄されてもイベント ソースが破棄されない場合、イベント ソースはサブスクライバーへの参照を保持しているため、サブスクライバーはガベージ コレクションされないことも理解しています。
- これを回避する一般的な方法は、オブジェクトが破棄される前に、ソースからサブスクライバーを明示的にサブスクライブ解除することです。プログラマーがこれがいつ発生するかを判断できない場合、これが問題になる可能性があることを理解しています。
上記から、イベントの使用がメモリリークを引き起こす可能性があることと、弱い参照パターンが必要な理由を理解していますが、理解を妨げているのは、弱いイベントパターンが実際にどのようにこの目標を達成するのですか? それは何が違うのですか?
確かに、イベントを管理するクラスがある場合でも、ハンドラーをソースにサブスクライブおよびサブスクライブ解除する必要があるため、参照が存在する必要があり、イベントを使用する標準的な方法で同じ問題が発生します。
誰かが私に欠けている、または誤解している基本的な概念を説明して、弱いイベントパターンを「理解」するのを手伝ってください。