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

发布于 2024-12-10 20:41:46 字数 608 浏览 0 评论 0原文

我有一个类:

public abstract class BaseComponent { ... }

在该类的构造函数中,我们订阅一个事件处理程序,例如,

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) { ... }

当涉及到 EventHandler 订阅和事件处理程序时,是否有任何硬性和快速的规则?取消订阅?

提供一些从 EventHandler 取消订阅函数的清理代码是否被认为是好的做法?即实现 IDisposable 并取消订阅 EventHandler?

还是我担心过度了?

I have a class:

public abstract class BaseComponent { ... }

Within the constructor of that class we subscribe to an event handler e.g.

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?

Is it considered good practice to provide some clean-up code that unsubscribes the function from the EventHandler? I.e. implement IDisposable and unsubscribe from the EventHandler then?

Or am I worrying unduly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

七月上 2024-12-17 20:41:46

如果您可以完全控制 BaseComponent 的使用,并且知道 EventObject 的生命周期比 BaseComponent 的生命周期短或相等*,则可以跳过取消订阅代码。

在所有其他情况下,我都会将其包括在内。在这种情况下,实现 IDisposable 是一种很好的风格。

*) 实际上,您将 eventObject 的生命周期耦合到 BaseComponent,因此它的生命周期不能更短,但当两者一起超出范围时它仍然可以相等。

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.

In all other cases I would include it. In this case implementing IDisposable is good style.

*) 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.

我的痛♀有谁懂 2024-12-17 20:41:46

只要公开事件的对象 (eventObject) 是在 BaseComponent 类中创建的 - 您就可以忽略显式取消订阅,因为它将自动被 GC 处理,但显式取消订阅无论如何都是一个好习惯。

但是,如果您要订阅由注入 BaseComponent 的外部对象公开的事件,您应该实现 IDisposableBaseComponent 类和 Dispose() 方法中进行清理。

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.

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.

猫烠⑼条掵仅有一顆心 2024-12-17 20:41:46

如果 eventObject 有可能活得更久,因为从 BaseComponent 派生的类的实例应该存在,那么您应该提供某种方法来显式触发取消订阅。否则,您将阻止组件的垃圾收集,因为 eventObject 持有对其的引用。

实现 IDisposable() 是实现此目的的好方法,只要您可以确保有一些代码实际调用它。终结器不会调用 Dispose(),因为只要组件订阅了 eventObject.ChangedEvent 并且 eventObject 仍然存在,垃圾收集器就不会尝试清理您的组件。

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. Otherwise you would prevent garbage collection of your component, as eventObject holds a reference to it.

Implementing IDisposable() is a good way to accomplish this as long as you can assure that there is some code actually calling it. 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文