简体   繁体   English

C#我应该手动删除我声明的事件处理程序吗?

[英]C# Should I manually remove the event handler I declared?

Okay, make an example here: 好的,举一个例子:

  1. I have UserControl A, UserControl B, UserControl C and one Windows Form. 我有UserControl A,UserControl B,UserControl C和一个Windows窗体。
  2. This Windows Form is only started with UserControl A. 此Windows窗体仅以UserControl A启动。
  3. UserControl C has [Next] and [Back] buttons. UserControl C有[Next]和[Back]按钮。
  4. Say, UserControl A is declared with an event handler. 比如说,UserControl A是用事件处理程序声明的。 One of function in UserControl A will actually raise the event call to execute one function at UserControl C. UserControl A中的一个函数实际上会引发事件调用以在UserControl C执行一个函数。
  5. So, at UserControl C, I have to add with 所以,在UserControl C,我必须添加

"UserControlA.OneFunction += this.UserControlC_Function;" “UserControlA.OneFunction + = this.UserControlC_Function;”

  1. If I click Next button at UserControl C, it will dispose the UserControl A and add new UserControl B to the Windows Form. 如果我在UserControl C上单击“下一步”按钮,它将处理UserControl A并将新的UserControl B添加到Windows窗体。 But I never remove this event handler manually. 但我从不手动删除此事件处理程序。

One of the function in UserControl A is the caller (where event is declared). UserControl A中的一个功能是调用者(声明事件的地方)。
One of the function in UserControl C is the listener. UserControl C中的一个功能是监听器。

So, these are my questions: 所以,这些是我的问题:

  • Should I manually remove the handler before UserControl A disposed? 我应该在UserControl A处理之前手动删除处理程序吗?
  • Will this User Control A dispose automatically remove the handler that declared previously? 此用户控件A dispose是否会自动删除之前声明的处理程序?
  • Should I add this somewhere? 我应该在某处添加吗?

"UserControlA.OneFunction -= this.UserControlC_Function;" “UserControlA.OneFunction - = this.UserControlC_Function;”

  1. By convention, we don't. 按照惯例,我们没有。 And since no event should be invoked after disposal, there is no need to do so unless the control in question is behaving weirdly. 并且由于在处置之后不应该调用任何事件,所以除非所讨论的控制行为奇怪,否则不需要这样做。
  2. No. At least there isn't such code as seen from reflector. 不,至少从反射器看不到这样的代码。

在这种情况下,您不需要删除处理程序,因为表单外部的代码都不会引用表单及其按钮,因此整个对象图将被垃圾回收。

The answer to this post does a really good job explaining when you need to manually remove an event handler and when it is not necessary. 这篇文章的答案非常好,可以解释何时需要手动删除事件处理程序以及何时不需要。

Do I need to remove event subscriptions from objects before they are orphaned? 我是否需要在孤立之前从对象中删除事件订阅?

If the form is released (assuming no other objects has a reference to the objects in question) there's little risk of not removing the event handler, however it's a good idea always to remove the event handler before the object listening can no longer be reach (ie all variables referencing the object i sout of scope) not doing so can create a memory leak. 如果表单被释放(假设没有其他对象具有对相关对象的引用),则不会删除事件处理程序的风险很小,但是在无法再访问对象之前始终删除事件处理程序是个好主意(即所有引用范围的对象的变量都没有这样做可能会造成内存泄漏。

This is not the case in your situation (if I get what you are describing, code would make it more clear) The problem would be if you attach a delegate referencing object C to an event on object A and then looses access to C (eg assigning a new value to the variable). 在你的情况下不是这种情况(如果我得到你所描述的内容,代码会使它更清晰)问题是如果你将一个委托引用对象C附加到对象A上的事件然后放弃对C的访问(例如为变量分配新值)。 C would then hang around until A is garbage collected 然后C会一直闲逛,直到A被垃圾收集

If the memory lifetime of an event publisher is not limited relative to the useful lifetime of an event subscriber, failure to unsubscribe an event will likely cause a memory leak. 如果事件发布者的内存生命周期不限于事件订阅者的有效生命周期,则取消订阅事件的失败可能会导致内存泄漏。 Were it not for the unfortunate hassle of doing so, there wouldn't be any reason for an event subscriber that was being disposed not to unsubscribe from all events, and for an event publisher that was being disposed not to nullify all event subscriptions. 如果不是因为这样做的不幸麻烦,就没有任何理由让事件订阅者被处理掉不取消订阅所有事件,并且事件发布者被处理不会使所有事件订阅无效。 Since neither C# nor VB provides any convenient means of doing those things, however, one has to balance the hassle of proper subscription handling with the fact that in many situations one can get away skimping on it. 然而,由于C#和VB都没有提供任何方便的方法来做这些事情,因此必须平衡正确订阅处理的麻烦与在许多情况下人们可以避免吝啬的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM