2017-12-03 15 views
1

私はUnder the hood of .NET memory management(Red-Gate発行)の本を読んでいます。 pdf version on their websiteが見つかります。ブック内のイベントハンドラ「.NETメモリ管理のフードの下で」

パブリッシャーとサブスクライバーの間で作成される参照に関してイベントハンドラーを理解していると思っていましたが、第5章「アプリケーション固有の問題」(タイトル「Windows Presentation Foundation」)のイベントハンドラーについては、私を混乱させる。

160-161ページには、マスター/詳細関係を使用するUIデザインが記述されています。あなたはマスタレコードのリスト でグリッドを有することができる

、あなたはをクリックすると:私は(角括弧の間の数字は、私の質問のための参照を作成するために、しゃれていないので、多くの意図した鉱山です)引用しますマスターグリッドからのレコード、新しいウィンドウ が開き、そのマスターレコードに関連付けられた詳細が表示されます。マスターウィンドウが詳細ウィンドウ[1]の イベントを配線する場合、マスターウィンドウの イベントハンドラが詳細ウィンドウ[2]への参照を解放するまで、詳細ウィンドウはガベージコレクションできません。この の場合、詳細ウィンドウはリスナーになり、マスターウィンドウはソース[3]になります。ほとんどの の場合、マスターウィンドウは詳細ウィンドウより長くなりますが、イベントハンドラが が正しく処理されないと、 マスターウィンドウが有効である限り、詳細ウィンドウをガベージコレクションできません。

Detail.SomeEvent += new EventHandler(Master.SomeEvent_Handler); [4] 

[1]これは非常に不明瞭な用語です。誰が "ワイヤーアップ"するのですか?これだけでは、誰がリスナーで、誰が加入者であるのかを判断することはできません。次の文章[3]は、マスターがソースであり、ディテールがリスナーであると言ってこのような疑問に答えるように見えるが、[2]で正反対のことを述べることによって混乱を招いた後である(ハンドラはマスターウィンドウでではありません)。

コード例[4]も[3]で述べられているものと一致しません(しかし、[2]に対応します)。マスターウィンドウがソースの場合は、次のようになります。

Master.SomeEvent += new EventHandler(Detail.SomeEvent_Handler); [5] 

右か?

この混乱の他に、私はイベントハンドラを次のように理解しています。 MasterにはDetailが([5]のように)サブスクライブするイベントがある場合、MasterDetailへのリフェンスを持ちます(この例では、インスタンス削除への参照によってインスタンスへの参照が作成されるためです)。従って、Masterが存在する限り、Detailも、イベントハンドラがイベントから切り離されていない限り、メモリに保持されます。

私の本の批判と私の理解は正しいですか?

答えて

1

C#構文の砂糖からは決して明らかになることはありません。デリゲートコンストラクタは2つの引数を取ります。明らかなのは、イベントハンドラメソッドです。自明でないものは、ハンドラメソッドが呼び出されるオブジェクトです。あなたが決してコードに入力しないので明白ではありません。 thisです。 C#はあなたがそれを指定することさえ許さず、他の言語はそれを行います。

したがって、Masterオブジェクトは、Detailオブジェクトへの参照をどのようにして、イベントハンドラメソッドを適切に呼び出す必要があります。

マスターオブジェクトが生存している限り、Detailオブジェクトは収集されません。明示的にイベントの再登録を解除するか、WPFの弱いイベントパターンを使用しない限り。または、理想的には、MasterオブジェクトとDetailオブジェクトが同時に死ぬようにコードを設計します。彼らはそれが簡単ではない例をあなたに与えました。

イベントを使用しない他の方法もあります。発生させたいイベントを表すメソッドでIDetailインターフェースを宣言することができます。そして、マスタークラスにAddDetail(IDetail)メソッドとRemoveDetail(IDetail)メソッドを与えます。今ではメモリ管理がはっきりしており、RemoveDetail()の呼び出しを忘れたときにははるかに明らかになります。しかし、WPFデザイナーは、代わりにイベントを使用することを強く好みました。彼らは、独自のオブジェクトモデルでのリークを避けるために、弱いイベントパターンを思いつく必要がありました。

+0

明白でない 'this'パラメータの意味は何ですか?それは文脈を設定しますか?(javascriptのように?(異端を許してください))?あなたはいくつかの書類や本を教えてもらえますか?私はこれについてもっと読んでみたいと思います。 – bvgheluwe

+0

特に深いものはありません。このイベントはインスタンスメソッドを呼び出すため、オブジェクト参照が必要です。デリゲートはそれを保存します。 Delegate.Targetプロパティに注意してください。どのように価値があるかを見るのはそれほど簡単ではありません。 –