鉴于 Control 类实现了 IDisposable,我认为 ASP.Net 至少能够触发 Dispose 级联,因为 Page 在离开浏览器的过程中完成了它的生命周期?
简单的问题:是这种情况,还是我必须这样做?
鉴于 Control 类实现了 IDisposable,我认为 ASP.Net 至少能够触发 Dispose 级联,因为 Page 在离开浏览器的过程中完成了它的生命周期?
简单的问题:是这种情况,还是我必须这样做?
它已经为你完成了。UnloadRecursive()
从System.Web.UI.Control
Reflector 中查看,由ProcessRequestCleanup()
.
不,您不应该在控件上调用 Dispose,这是正在完成的。您负责在 Control 结构(FileStreams 等)之外创建的其他 Disposable 对象。
这遵循一般的 .NET 原则:页面是控件的所有者,因此需要将(显式)Dispose 级联到它们。对于实际代码,您必须反射 Web.UI.Control 的代码。
这篇关于ASP.NET 页面生命周期的文章指出:
“在页面完全呈现、发送到客户端并准备好被丢弃后调用卸载。此时,响应和请求等页面属性被卸载并执行任何清理。”
我认为“任何清理”意味着处理控件等。我无法想象 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
是一个更安全的选择。