当前位置: 首页 > 编程语言 > C#

有趣的事件“Dispose”行为分享

时间:2023-04-10 16:13:17 C#

有趣的事件“Dispose”行为我注意到我们的.NETWinForms应用程序中有一个有趣的行为。我们有一个mdi表单,其中添加了许多mdi子项。这些子窗体监听“广播”事件,其实就是调用刷新自己。事件在基类中声明,监听事件在子窗体中添加。我注意到即使关闭了这些子窗体,如果未在Dispose()方法中明确删除它们,事件仍然会被触发。这背后的原因是什么?如果表单关闭,当然应该分离/处理事件?是因为实际事件本身是在外部类中声明的吗?那是我的假设。洞察力将不胜感激。(使用C#、.NET3.5)事件仍在范围内,因为它在主窗体上,并且委托仍在子窗口中引用。因此,关闭窗口并不会丢弃该对象,因为它仍在该引用的范围内。这是在.NET中出现“内存泄漏”的一种非常常见的方法。还要考虑因为子窗口仍在范围内,所以窗口内的所有内容仍在范围内并且不会被收集。至于为什么窗口在关闭时不分离所有事件处理程序。如果这样做,那将是非常奇怪的行为。仅仅因为您关闭了一个窗口并不意味着您已经完成了它,您可以重新打开它,将数据保存到持久状态。在窗口上调用close没有调用任何其他方法的特殊属性,它不会丢弃窗口、将其标记为集合或其他任何内容。你是对的。注册事件时,将对表单的引用添加到事件委托(在拥有事件的对象中)。除非您删除注册,否则您的表单将永远不会被垃圾收集,因为它仍然至少有一个对它的引用(代理),并且在引发事件时仍会进行调用。您应该始终确保取消订阅事件以避免此类泄漏。是的,这是设计使然的行为,这就是满足WeakEvent模式的原因。您的有效订阅在您的子表单中被“算作”参考。(因此您的子表单也不会被垃圾收集)。要查看发生了什么,请寻求代表的帮助。它有一个名为Target(对象类型)的成员指向订阅者。因此,您仍然有一个引用链:MDIParent(事件发布者)->delegate->您的子表单。您必须在Dispose()中清理您的事件订阅,否则您的子表单将永远无法进行垃圾回收。现在,如果您浏览Web以查找“弱参考事件”,您会发现人们发布了一些解决方法来定义弱事件。这只是一个示例:http://www.codeproject.com/KB/cs/weakeventhandlerfactory.aspx我还必须对原型进行原型制作,如果您愿意,我很乐意与您分享。但是,我的建议是坚持定期事件并在Dispose()中进行清理。以上就是《C#学习教程:趣味事件“处置”行为分享》的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。侵权请点击右侧联系管理员删除。如需转载请注明出处: