C# 我应该手动删除我声明的事件处理程序吗?
好的,在这里举个例子:
- 我有 UserControl A、UserControl B、UserControl C 和一个 Windows 窗体。
- 此Windows 窗体仅由UserControl A 启动。UserControl
- C 有[下一步] 和[后退] 按钮。
- 比如说,UserControl A 是用事件处理程序声明的。 UserControl A 中的函数之一实际上会引发事件调用以执行 UserControl C 中的一个函数。
- 因此,在 UserControl C 中,我必须添加 with
“UserControlA.OneFunction += this.UserControlC_Function;”
- 如果我单击 UserControl C 上的“下一步”按钮,它将处理 UserControl A 并将新的 UserControl B 添加到 Windows 窗体。但我从来没有手动删除这个事件处理程序。
UserControl A 中的函数之一是调用者(在其中声明事件)。
UserControl C 中的功能之一是监听器。
所以,这些是我的问题:
- 我应该在 UserControl A 处置之前手动删除处理程序吗?
- 此用户控件 A 处置会自动删除先前声明的处理程序吗?
- 我应该在某个地方添加这个吗?
“UserControlA.OneFunction -= this.UserControlC_Function;”
Okay, make an example here:
- I have UserControl A, UserControl B, UserControl C and one Windows Form.
- This Windows Form is only started with UserControl A.
- UserControl C has [Next] and [Back] buttons.
- Say, UserControl A is declared with an event handler. One of function in UserControl A will actually raise the event call to execute one function at UserControl C.
- So, at UserControl C, I have to add with
"UserControlA.OneFunction += this.UserControlC_Function;"
- If I click Next button at UserControl C, it will dispose the UserControl A and add new UserControl B to the Windows Form. But I never remove this event handler manually.
One of the function in UserControl A is the caller (where event is declared).
One of the function in UserControl C is the listener.
So, these are my questions:
- Should I manually remove the handler before UserControl A disposed?
- Will this User Control A dispose automatically remove the handler that declared previously?
- Should I add this somewhere?
"UserControlA.OneFunction -= this.UserControlC_Function;"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在这种情况下,您不需要删除处理程序,因为表单及其按钮都不会被表单外部的代码引用,因此整个对象图将被垃圾收集。
You don't need to remove the handlers in this case because neither the form nor its buttons are referenced by code external to the form, and the entire object graph will therefore be garbage collected.
这篇文章的答案很好地解释了何时需要手动删除事件处理程序以及何时不需要。
我需要吗在对象成为孤立对象之前从对象中删除事件订阅?
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?
如果表单被释放(假设没有其他对象引用相关对象),则不删除事件处理程序的风险很小,但是最好始终在无法再访问对象侦听之前删除事件处理程序(即引用该对象的所有变量都超出了范围),不这样做可能会导致内存泄漏。
您的情况并非如此(如果我明白您所描述的内容,代码会让它更清楚)
问题在于,如果您将引用对象 C 的委托附加到对象 A 上的事件,然后失去对 C 的访问权限(例如,为变量分配新值)。然后 C 会一直徘徊直到 A 被垃圾回收
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 (e.g. assigning a new value to the variable). C would then hang around until A is garbage collected
如果事件发布者的内存生命周期相对于事件订阅者的有用生命周期不受限制,则无法取消订阅事件可能会导致内存泄漏。如果不是因为这样做会带来不幸的麻烦,那么事件订阅者就没有任何理由不取消所有事件的订阅,事件发布者也没有任何理由不取消所有事件订阅。然而,由于 C# 和 VB 都没有提供任何方便的方法来执行这些操作,因此必须在正确处理订阅的麻烦与在许多情况下可以省去处理这一事实之间取得平衡。
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.