1

イベントを発生させるクラス(ユーザーコントロール)MyUserControlがあります。

私はそれを形MyFormで使用します、その点で、私はいくつかの理由でペアAddHandlerの代わりに使用することを余儀なくされています。WithEvents<>Handles

AddHandlerメソッドでsを使用しMyForm_Loadます。

今。ハンドラーの追加はOKです。問題は、このハンドラーをどこで削除するかです。FinalizeMyFormのメソッドで実行する必要がありますか?アラ

Protected Overrides Sub Finalize()
  RemoveHandler _myCtrl.Action1Performed, AddressOf MyControl_Action1Performed  
  RemoveHandler _myCtrl.Action2Performed, AddressOf MyControl_Action2Performed  
  RemoveHandler _myCtrl.Action3Performed, AddressOf MyControl_Action3Performed  
End Sub
4

4 に答える 4

5

コンテナコントロール(フォームなど)が破棄されると、そのすべてのイベントハンドラーが自動的に削除され、破棄されます。ユーザーコントロールもそのコンテナフォームももう存在しないため、このクリーンアップは自動的に行われます。

呼び出しについて本当に心配する必要がRemoveHandlerあるのは、コンテナーよりも大幅に長い寿命が期待されるオブジェクトにイベントハンドラーを接続する場合だけです。その場合、そのハンドラーがサブスクライブされている限り、そのオブジェクトをガベージコレクションできないため、メモリリークが発生する可能性があります。Tess Ferrandezのブログで、はるかに包括的なケーススタディを読むことができます。両方のオブジェクトが同時に「スコープ外」になった場合、これは問題ではありません。

編集:それでもハンドラーを絶対に削除する必要があると感じている場合(おそらく強迫神経症ですか?)、フォームのDisposeメソッドでそれを実行できます。純粋主義者は、このようなものの使用を躊躇するかもしれませんがIDisposable、悪い結果は見られません。Finalizeただし、このためのメソッドを実装しないようにする必要があります。意味がありません。オブジェクトへの強力な参照がなくなるまでファイナライザーメソッドは呼び出されませんが、呼び出しに失敗した場合に考えられるRemoveHandler唯一の害は、コンテナーがそのオブジェクトへの参照を必要以上に長く保持することです。Finalizeメソッド内のイベントハンドラーを削除しようとして、自分をだましています。

また、 /の目的はイベントハンドラーを動的に追加および削除できるようにすることであるため、正確にどこで実行するかは実際には重要ではないことにも注意してください。コード内の任意の場所でそれらを呼び出すことができます。AddHandlerRemoveHandler

于 2011-01-28T10:43:29.063 に答える
1

フォームがUserControlの所有者であるとすると、クリーンアップはまったく必要ありません。

のようなハンドラーがAddressOf OtherObject.Action1Performedあり、OtherObjectがフォームよりも長持ちする場合は、ハンドラーを削除する必要があります。


編集:

'where'について:ではありませんSub Finalize

Dispose()メソッドを使用できます(C#ではDesignerファイルから移動できます)。それ以外の場合は、FormClosedイベントを使用します。

ここではファイナライザーは必要ありませんが、かなりのコストがかかります。

于 2011-01-28T10:41:09.403 に答える
0

ハンドラーを削除する理由がわからない場合は、次のポストバックでハンドラーが不要になり、ページの読み込み時に条件付きで再度設定しない限り、ハンドラーをポストバックごとに使用する場合は、GCに廃棄を処理させる必要があります。

于 2011-01-28T10:39:59.760 に答える
0

オブジェクトのファイナライザーは、そのオブジェクトのイベントサブスクリプションをクリーンアップするのに役立ちません。オブジェクトがサブスクライブしているすべてのイベントのすべての発行者が範囲外になるまで起動しません。それが発生すると、イベントのクリーンアップの問題は無効になります。この目的でファイナライザーを作成すると、ファイナライズ可能なオブジェクトがそれ自体と、直接または間接参照を保持するオブジェクトのガベージコレクションを遅らせるため、実際には逆効果になります。

習慣として、イベントのサブスクリプションをクリーンアップすることをお勧めします。パブリッシャーとサブスクライバーの存続期間が等しい場合、イベントサブスクリプションを管理対象リソースと見なすことができますが、存続期間の長いオブジェクトからのイベントは管理対象外のリソースです。他の場所でクリーンアップされていない場合は、Disposeでクリーンアップする必要があります(Disposeは、他の場所でクリーンアップするための「バックストップ」である必要があります)。短命のオブジェクトのイベントサブスクリプションを無視することはできますが、そのような方法では、どのイベント発行者が長命であるか、または長命である可能性があるかを特定する必要があります。また、オブジェクトがスコープ外になったときにイベントのサブスクライブを定期的に解除すると、偶発的なイベントを見逃した場合に発生する可能性のあるダメージが制限されることにも注意してください。おそらく短命のオブジェクトからのイベントが放棄されたが、1つの長命のオブジェクトのイベントも放棄された場合、長命のオブジェクトがガベージコレクションの対象になるまで、短命のオブジェクトはガベージコレクションの対象になりません。

于 2011-02-01T20:04:48.270 に答える