Asp.net 解释对象的生存期超出范围的原因

Asp.net 解释对象的生存期超出范围的原因,asp.net,database-connection,Asp.net,Database Connection,我写了一节课,如下所示。我写这篇文章时考虑到它主要用于web(即,它将从aspx页面使用) 我已经编写了我的aspx页面代码,如下所示: public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { TestHelper helper = new TestHelper(); helper

我写了一节课,如下所示。我写这篇文章时考虑到它主要用于web(即,它将从aspx页面使用)

我已经编写了我的aspx页面代码,如下所示:

public partial class _Default : System.Web.UI.Page 
{    
    protected void Page_Load(object sender, EventArgs e)
    {
        TestHelper helper = new TestHelper();
        helper = null;
    }

}
尽管将helper赋值为“null”,但我发现
CurrentPage\u Unload()
得到了执行。为什么这种行为如此?这种行为通常被称为什么


我之所以以这种风格编写这个类,是因为我认为我可以以一种集中的方式在类中最好地管理我的db连接。通常人们会调用对象上的方法,比如在aspx代码中调用
helper.IsValid()
,然后调用
helper.ProfileExists()
。每个方法都有自己的db连接对象(IDbConnection),以及相应的
Open()
&
Close()
打开/关闭db连接的调用。我只是觉得我们应该在代码中只做一次。因此,我使用构造函数打开db连接,使用页面对象的卸载事件关闭连接对象。以这种方式编写类有什么缺陷吗?

null
赋值给变量并不会结束它的实际生存期。由于.NET使用的是非确定性垃圾收集系统(在该系统中,对象会根据多个条件定期清除,而不是在对象超出范围后立即清除),因此在创建对象的进程结束之前,您无法依赖对象被收集


此外,由于要将事件处理程序(即委托,其中包含对新构造实例的引用)附加到另一个对象,因此也在延长对象的生存期。只要附加了该事件处理程序,就无法收集对象,直到附加到的对象符合条件。

发生的情况是将委托附加到页面的卸载事件。即使将变量设置为null,页面仍然存在,并且仍然有一个卸载事件,该事件仍然保存对添加到其中的委托的引用

要删除代理,需要使用
-=
语法

CurrentPage.Unload -= new EventHandler(CurrentPage_Unload); 

您必须考虑执行该行时会发生什么

helper = null;
您只需要引用一个对象。将该对象指定为null时,只需将引用设置为null。这个物体什么也没发生。考虑下面的代码:

var first = new object();
second = first;

first = null;
第二个现在是空的吗?你可以把一个引用想象成一个简单的数字——它只是内存中对象的地址


NET垃圾收集器只是查看对象并检查是否存在对该对象的引用。如果没有,它将删除该对象。

应该读CurrentPage_Unload(),在这里写CustomPage_Unload()?因为页面的卸载连接到我正在实例化的类的一个方法,GC会实际收集该类的实例吗?@DeoWalk:这就是我在第二段中试图得到的。将对象(
this
)附加到
CurrentPage
Unload
事件(存在于类之外的引用,因为它来自
RequestHandler
)意味着对
this
的引用将作为
RequestHandler
上的事件处理程序的一部分存储。这意味着在
RequestHandler
中引用的对象符合条件或者您从事件中分离之前,您的对象不符合垃圾收集的条件。
var first = new object();
second = first;

first = null;