17

鉴于 Control 类实现了 IDisposable,我认为 ASP.Net 至少能够触发 Dispose 级联,因为 Page 在离开浏览器的过程中完成了它的生命周期?

简单的问题:是这种情况,还是我必须这样做?

4

4 回答 4

9

它已经为你完成了。UnloadRecursive()System.Web.UI.ControlReflector 中查看,由ProcessRequestCleanup().

于 2009-07-28T10:25:40.853 回答
5

不,您不应该在控件上调用 Dispose,这是正在完成的。您负责在 Control 结构(FileStreams 等)之外创建的其他 Disposable 对象。

这遵循一般的 .NET 原则:页面是控件的所有者,因此需要将(显式)Dispose 级联到它们。对于实际代码,您必须反射 Web.UI.Control 的代码。

于 2009-07-28T08:08:53.470 回答
2

这篇关于ASP.NET 页面生命周期的文章指出:

“在页面完全呈现、发送到客户端并准备好被丢弃后调用卸载。此时,响应和请求等页面属性被卸载并执行任何清理。”

我认为“任何清理”意味着处理控件等。我无法想象 ASP.NET 框架的设计者会忽略这一点,而没有人会注意到。

于 2009-07-28T08:59:32.493 回答
1

以不同的方式解释,这个问题比看上去更复杂。

当然Disposed会被调用,但它有什么作用吗?这取决于。

如果您订阅Disposed了页面或控件的事件,并希望它被按请求调用,您可能会感到惊讶。是的,从技术上讲ProcessRequestCleanup(),它是为你调用的,但看看它实际调用的是什么:

public virtual void Dispose()
{
    IContainer service = null;
    if (this.Site != null)
    {
        service = (IContainer) this.Site.GetService(typeof(IContainer));
        if (service != null)
        {
            service.Remove(this);
            EventHandler handler = this.Events[EventDisposed] as EventHandler;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    }
    if (this._occasionalFields != null)
    {
        this._occasionalFields.Dispose();
    }
}

如果没有设计界面,此代码在运行时基本上什么都不做,这意味着您的Disposed处理程序将永远不会执行。

教训是不要依赖Disposed处理程序来执行每个请求。您可以覆盖它以保证执行某些操作,但这Unloaded是一个更安全的选择。

于 2011-03-15T17:24:33.310 回答