C# 删除处理对象时的处理程序

C# 删除处理对象时的处理程序,c#,.net,C#,.net,我可以想出一些混乱的方法来解决这个问题,但我觉得应该有一个比我已经想出的更优雅的解决方案 对于一个对象来说,最合适的方式是在处理之前清除其自身的所有事件处理程序。很遗憾,事件处理程序无法枚举 从理论上讲,将处理程序添加到对象中的代码记住删除它是否比假设对象在超出范围之前将自己清理干净更正确 从理论上讲,它被认为更重要吗 对于添加 要记住的对象的处理程序 移除它,而不是假设对象 会在它走之前把自己清理干净 超出范围 对于上述问题,我不得不说是的。关于事件的基本理论是,事件触发者不应该负责管理自己的

我可以想出一些混乱的方法来解决这个问题,但我觉得应该有一个比我已经想出的更优雅的解决方案

对于一个对象来说,最合适的方式是在处理之前清除其自身的所有事件处理程序。很遗憾,事件处理程序无法枚举

从理论上讲,将处理程序添加到对象中的代码记住删除它是否比假设对象在超出范围之前将自己清理干净更正确

从理论上讲,它被认为更重要吗 对于添加 要记住的对象的处理程序 移除它,而不是假设对象 会在它走之前把自己清理干净 超出范围


对于上述问题,我不得不说是的。关于事件的基本理论是,事件触发者不应该负责管理自己的处理程序;添加事件的人应该进行清理。

有一种方法可以避免事件的这种常见问题-。

事件处理程序对我来说是.NET应用程序内存消耗的最大威胁,特别是当您开始在web服务器上下文中使用它时。对我来说,它始终是附属于deattach的对象的责任。附加对象的寿命应始终小于或等于它所附加的对象的寿命,否则事件的设计会出现问题,因为您不希望再收到关于对象中没有任何意义的更改的通知。如果它们的寿命相等,它们将一起超出范围,您无需执行任何操作,如果寿命较短,则附着对象必须分离。在一个基本的web应用程序中,您只有3种类型的生命周期:应用程序、会话和页面,这些规则很容易应用。在更复杂的应用程序中,这需要更多的思考。

在我的设计中,我非常严格地定义合同,如:

  • 每个资源获取必须与发布配对
  • 每次启动服务的呼叫必须与停止服务的呼叫配对
  • 每个附加到对象的观察者都必须分离
  • 等等
(这样的契约并不罕见,比如您必须对文件的打开和关闭进行配对,或者对不采用自动垃圾收集的语言中的new/delete调用进行配对)

这些契约中的每一个都可以在运行时进行一定程度的测试。例如,可以检测并报告一个观察者分离的次数超过其连接的次数(断言或异常取决于情况)

因此,你的问题是:

从理论上讲,它被认为更重要吗 对于添加 要记住的对象的处理程序 移除它,而不是假设对象 会在它走之前把自己清理干净 超出范围

这是正确的。答案是肯定的,不仅在理论上,在实践中也是如此。在我看来,这些合同有助于你避免大错特错


按照这种方式思考,您就可以很好地构建真正健壮的软件。

很公平。非常感谢您快速而有用的回答。