鉴于Control类实现了IDisposable,我认为ASP.Net至少能够触发Dispose级联,因为Page在浏览器出门的路上完成了它的生命周期?
简单问题:是这种情况,还是我必须这样做?
答案 0 :(得分:8)
它已经为你完成了。查看Reflector中UnloadRecursive()
的{{1}},该System.Web.UI.Control
由ProcessRequestCleanup()
调用。
答案 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
是一个更安全的赌注。