ASP.Net是否在页面中的页面/控件上调用Dispose,或者我必须这样做吗?

时间:2009-07-28 08:05:26

标签: asp.net idisposable

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

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

4 个答案:

答案 0 :(得分:8)

它已经为你完成了。查看Reflector中UnloadRecursive()的{​​{1}},该System.Web.UI.ControlProcessRequestCleanup()调用。

答案 1 :(得分:5)

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

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

答案 2 :(得分:2)

关于The ASP.NET Page Life Cycle的这篇文章指出:

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

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

答案 3 :(得分: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是一个更安全的赌注。