【发布时间】:2009-07-28 08:05:25
【问题描述】:
鉴于 Control 类实现了 IDisposable,我认为 ASP.Net 至少能够触发 Dispose 级联,因为 Page 在离开浏览器的过程中完成了它的生命周期?
简单的问题:是这样吗,还是我必须这样做?
【问题讨论】:
标签: asp.net idisposable
鉴于 Control 类实现了 IDisposable,我认为 ASP.Net 至少能够触发 Dispose 级联,因为 Page 在离开浏览器的过程中完成了它的生命周期?
简单的问题:是这样吗,还是我必须这样做?
【问题讨论】:
标签: asp.net idisposable
它已经为你完成了。从Reflector中的System.Web.UI.Control看UnloadRecursive(),被ProcessRequestCleanup()调用。
【讨论】:
不,您不应该在控件上调用 Dispose,这是正在完成的。您负责在 Control 结构(FileStreams 等)之外创建的其他 Disposable 对象。
这遵循一般的 .NET 原则:页面是控件的所有者,因此需要将(显式)Dispose 级联到它们。对于实际代码,您必须反射 Web.UI.Control 的代码。
【讨论】:
The ASP.NET Page Life Cycle 上的这篇文章指出:
“在页面完全呈现后调用卸载,发送到客户端,并准备好被丢弃。此时,响应和请求等页面属性被卸载并执行任何清理。”
我认为“任何清理”意味着处理控件等。我无法想象 ASP.NET 框架的设计者会忽略这一点,而没有人会注意到。
【讨论】:
换个说法,这个问题比表面上看起来更复杂。
当然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 是更安全的选择。
【讨论】: