我正在阅读书Under the hood of .NET memory management
(由Red-Gate出版)。您可以在他们的网站上找到PDF版本。
我以为我了解了事件处理程序有关发布者和订阅者之间创建的参考文献的理解,但是作者在第5章"应用程序特定问题"中对事件处理程序的解释(标题为" Windows Edentation Foundation")我。
在第160-161页上,他们描述了使用主/细节关系的UI设计。我引用(方括号之间的数字是我的,为了为我的问题创建参考,双关语不是很多意图):
您可能有一个带有列表的网格 主记录,当您单击主电网的记录时,一个新窗口 打开与该主记录相关的详细信息。如果主窗口上线 详细信息窗口中的事件[1],那么细节窗口才能收集到垃圾 主窗口中的事件处理程序将其引用到"详细信息"窗口[2]。在这个 情况,详细信息将是侦听器,主窗口是源[3]。多数情况 情况,主窗口将超过详细信息窗口,但是如果事件处理程序为 无法正确处理,那么只要 主窗还活着。
Detail.SomeEvent += new EventHandler(Master.SomeEvent_Handler); [4]
[1]这是非常不清楚的术语。谁"登上"谁?仅凭这一点,我无法确定谁是听众,谁是订户(我只能假设...)。下一个句子[3]似乎是通过说主是来源的,而细节是听众,但是只有在引入混乱之后,就通过在[2]中说明了相反的混乱(因为事件 handlers handlers 是不是主窗口中的)。
代码示例[4]也与[3]中所述的内容不符(但与[2]相对应。如果主窗口是源,则应该是:
Master.SomeEvent += new EventHandler(Detail.SomeEvent_Handler); [5]
对吗?
除了所有这些混乱之外,我了解事件处理程序如下。如果Master
具有Detail
订阅的事件(如[5]中),则Master
对Detail
有所改善(因为在这种情况下,对实例的引用删除了对实例的引用Detail
)。因此,只要Master
活着,Detail
也将在记忆中保存,除非事件处理程序与事件分离。
我对本书的批评和我自己的理解是正确的吗?
从C#语法糖中永远不会很明显。代表构造函数在引擎盖下采取两个。显而易见的是事件处理程序方法。非显而易见的是其处理程序方法将被称为的对象。不太明显,因为您永远不会在代码中键入它。是this
。C#甚至不允许您指定它,其他语言也可以。
因此,主对象现在如何引用对详细对象的引用,这是正确调用事件处理程序方法所必需的。
,只要主对象还活着,细节对象就不会收集。除非您再次明确订阅事件或使用WPF弱事件模式。或者,理想情况下,设计代码,使主和细节对象同时死亡。他们给了你一个例子,这并不容易。
还有其他方法不使用事件。您可以使用代表要提出的事件的方法声明idetail接口。并给主类一个AddDetail(idetail)和删除(Idetail)方法。现在,内存管理是清晰的,当您忘记致电removeTail()时,它变得更加明显。但是,WPF设计师反而强烈喜欢使用事件,他们必须提出薄弱的事件模式,以避免自己的对象模型中的泄漏。