【问题标题】:Eventhandlers and application lifetime objects in c# - should I unhook?c# 中的事件处理程序和应用程序生命周期对象 - 我应该取消挂钩吗?
【发布时间】:2010-11-23 04:20:59
【问题描述】:

假设我有一个在应用程序期间存在的对象。我们称它为 GlobalWorker。 GlobalWorker 有事件,例如其他对象可以订阅的 UserLoggedIn。现在想象一下,我有一个 Silverlight 页面或一个 asp.net 页面或其他东西,它在构造时订阅了 UserLoggedIn 事件。

public SomePage()
{
GlobalWorker.Instance.UserLoggedIn += new EventHandler(OnUserLoggedIn);
}

private void OnLoggedIn(object sender, EventArgs e)
{

}

此事件的存在是否会阻止页面被垃圾收集?如果是这样,在这种情况下使用的最佳模式是什么:弱事件处理程序,将订阅移动到 Load 事件并在 UnLoad 事件中取消订阅?

【问题讨论】:

    标签: c# event-handling


    【解决方案1】:

    使用Weak Events

    这是 WPF 中的一个常见问题,您已经考虑过了。

    【讨论】:

    • 这也是 Windows 窗体中的常见问题。
    • 见鬼,甚至是 JavaScript 的问题!
    • “弱事件”模式是否比简单地在侦听器类中取消注册事件处理程序更可取,因为它更通用(并且需要更少的[冗余]代码)?
    • 有时您无法明确取消注册,这是我看到弱事件模式浮出水面的地方,知道您经常明确取消挂钩是一种好习惯,并让您了解周围环境。
    【解决方案2】:

    是的,该行为阻止了页面被 GC。

    原因是 UserLoggedIn 将无限期地持有对 SomePage 的引用。没有显式删除处理程序,并且由于未使用 weak events,因此也不会隐式删除。

    你可以像另一张海报所说的那样使用弱事件,你也可以在某种程度上重新思考你的设计,看看你是否可以函数化或封装事件行为。在这种情况下(用户凭据),数据可能就是全局所需的全部内容,因为事件可以保持隔离。

    如果这是您关心的一次性事件,您也可以在处理程序本身中取消注册。这真的归结为您的特定需求和实例,弱事件模式是在整个应用程序范围内处理此应用程序的模式,但并不意味着您必须在此问题出现的每个实例中都使用该模式。

    【讨论】:

    • 很多地方都有想诉诸WeakEvent的倾向,不是吗?也许这是一种懒惰的倾向——即不考虑应用程序的处理方面。似乎在大多数地方,稍微重新思考一下就可以消除对 WeakEvent 的需求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多