Ответ 1
Это сделано для вас. Посмотрите UnloadRecursive()
из System.Web.UI.Control
в Reflector, который вызывается ProcessRequestCleanup()
.
Учитывая, что класс Control реализует IDisposable, я думаю, что ASP.Net, по крайней мере, способен запускать каскад Dispose по мере того, как страница заканчивает жизненный цикл при выходе из браузера?
Простой вопрос: это так, или я должен это делать?
Это сделано для вас. Посмотрите UnloadRecursive()
из System.Web.UI.Control
в Reflector, который вызывается ProcessRequestCleanup()
.
Нет, вы не должны вызывать Dispose на элементах управления, которые выполняются. Вы несете ответственность за другие одноразовые объекты, созданные за пределами структуры управления (FileStreams и т.д.).
Это следует из общего принципа .NET: Страница является владельцем элементов управления и поэтому требует каскадирования (явно) Dispose к ним. Для фактического кода вам потребуется Reflector код для 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
- гораздо более безопасная ставка.