Вызывает ли ASP.Net Dispose на странице/элемента управления на странице, или я должен это делать?

Учитывая, что класс Control реализует IDisposable, я думаю, что ASP.Net, по крайней мере, способен запускать каскад Dispose по мере того, как страница заканчивает жизненный цикл при выходе из браузера?

Простой вопрос: это так, или я должен это делать?

Ответы

Ответ 1

Это сделано для вас. Посмотрите UnloadRecursive() из System.Web.UI.Control в Reflector, который вызывается ProcessRequestCleanup().

Ответ 2

Нет, вы не должны вызывать Dispose на элементах управления, которые выполняются. Вы несете ответственность за другие одноразовые объекты, созданные за пределами структуры управления (FileStreams и т.д.).

Это следует из общего принципа .NET: Страница является владельцем элементов управления и поэтому требует каскадирования (явно) Dispose к ним. Для фактического кода вам потребуется Reflector код для Web.UI.Control.

Ответ 3

В этой статье Жизненный цикл страницы ASP.NET говорится, что:

"Выгрузка вызывается после того, как страница была полностью отображена, отправлена ​​клиенту и готова быть отброшена. На этом этапе свойства страницы, такие как" Ответ и запрос ", выгружаются и выполняется любая очистка".

Я бы сказал, что "любая очистка" означает удаление элементов управления и т.д. Я не могу представить, чтобы дизайнеры структуры ASP.NET не обратили внимания на это, и никто не заметил бы.

Ответ 4

Интерпретируя по-другому, есть более сложный вопрос, чем кажется на первый взгляд.

Конечно, 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 - гораздо более безопасная ставка.