简体   繁体   English

C#事件处理程序订阅管理

[英]C# Event handler subscription management

I have a class: 我有一节课:

public abstract class BaseComponent { ... }

Within the constructor of that class we subscribe to an event handler eg 在该类的构造函数中,我们订阅了一个事件处理程序,例如

protected ObjectWithEventHandler eventObject { get; private set; }

public BaseComponent (ObjectWithEventHandler obj)
{
    eventObject = obj;
    eventObject.ChangedEvent += new EventHandler(eventObject_OnChangedEvent );
}

protected void eventObject_OnChangedEvent (object sender, EventArgs e) { ... }

Are there any hard and fast rules when it comes to EventHandler subscription & unsubscription? 在涉及EventHandler订阅和取消订阅时,是否有任何严格的规则?

Is it considered good practice to provide some clean-up code that unsubscribes the function from the EventHandler? 提供一些取消订阅EventHandler函数的清理代码是否被认为是一种好习惯? Ie implement IDisposable and unsubscribe from the EventHandler then? 即实现IDisposable并取消订阅EventHandler呢?

Or am I worrying unduly? 还是我过度担心?

As long as object which exposes event ( eventObject ) is created inside a BaseComponent class - you can ignore explicit unsubscribing because it will be GCed automatically but explicit unsubscribe is a good practice anyway. 只要暴露事件( eventObject )的对象是在BaseComponent类中创建的 - 您可以忽略显式取消订阅,因为它将自动GCed但是显式取消订阅无论如何都是一个好习惯。

But if you're subscribing for event which exposed by an external object injected into BaseComponent you should implement IDisposable in the BaseComponent class and in the Dispose() method do cleanup. 但是,如果您正在订阅由注入BaseComponent的外部对象公开的事件,则应在BaseComponent类中实现IDisposable ,并在Dispose()方法中执行清理。

If you have full control of the usage of BaseComponent and you know that EventObject's lifecycle is shorter or equal* with regard to BaseComponent's lifecycle, you can skip unsubscription code. 如果您完全控制BaseComponent的使用,并且您知道EventObject的生命周期相对于BaseComponent的生命周期更短或相等*,则可以跳过取消订阅代码。

In all other cases I would include it. 在所有其他情况下,我会包括它。 In this case implementing IDisposable is good style. 在这种情况下,实现IDisposable是一种很好的风格。

*) effectively, you are coupling eventObject's lifetime to BaseComponent, so it cannot live shorter, but it could still be equal when the two go out of scope together. *)实际上,你将eventObject的生命周期耦合到BaseComponent,因此它不能短,但当两者一起超出范围时它仍然可以相等。

You should provide some way to trigger unsubscription explicitly if there is any chance that the eventObject might live longer as instances of the classes derived from BaseComponent are supposed to live. 如果由于BaseComponent派生的类的实例应该存在,则eventObject可能会活得更久,您应该提供一些显式触发取消订阅的方法。 Otherwise you would prevent garbage collection of your component, as eventObject holds a reference to it. 否则,您将阻止组件的垃圾收集,因为eventObject包含对它的引用。

Implementing IDisposable() is a good way to accomplish this as long as you can assure that there is some code actually calling it. 实现IDisposable()是一种很好的方法,只要你能确保有一些代码实际调用它。 The finalizer would not call Dispose(), because the garbage collector would not try to clean up your component as long as it is subscribed to eventObject.ChangedEvent and eventObject is still alive. 终结器不会调用Dispose(),因为只要订阅了eventObject.ChangedEvent并且eventObject仍处于活动状态,垃圾收集器就不会尝试清理你的组件。

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

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