Application_Start против OnInit против конструктора - PullRequest
7 голосов
/ 23 июля 2010

Я обходил это с тех пор, как начал программировать классический ASP 12 (или около того) несколько лет назад, и я никогда не находил отличного решения, потому что архитектура ASP и ASP.NET всегда была кучей плохих практик.магия общих синглетонов и т. д. Моя самая большая проблема связана с объектом HttpApplication с его событиями, не относящимися к событию (Application_Start, Application_End и т. д.).

Если выЕсли вы хотите сделать что-то один раз за весь срок службы HTTP-приложения, Application_Start является очевидным местом для этого.Правильно?Не совсем.Во-первых, это не событие само по себе, это магическое соглашение об именах, которое, при его соблюдении, приводит к тому, что метод вызывается один раз для AppDomain, созданного IIS.

Помимо магических соглашений об именах, являющихся ужасной практикой, я 'Мы начали думать, что это может быть причиной того, что на объекте HttpApplication не существует такого явления, как Start.Поэтому я экспериментировал с событиями, которые существуют, такими как Init.Ну, на самом деле это тоже не событие, это перезаписываемый метод, который является следующим лучшим решением.

Кажется, что метод Init() вызывается для каждого экземпляра объекта HttpApplication, которыйслучается гораздо чаще, чем один раз за домен приложения.Это означает, что я мог бы просто поместить свою логику запуска в конструктор объекта HttpApplication.

Теперь мой вопрос: почему я не должен помещать свою логику запуска в конструктор?Почему даже Init() существует, и мне нужно заботиться о Application_Start?Если я это сделаю, может кто-нибудь объяснить, почему в объекте HttpApplication нет подходящего события или переопределенного метода для этого псевдо-события?

И кто-нибудь может объяснить мне, почему в типичном приложении ASP.NET 8создаются экземпляры моего HttpApplication (что приводит к тому, что конструктор и Init запускаются столько же раз, разумеется; это можно уменьшить с помощью блокировки и общего статического логического значения, называемого initialized), когда мое приложение имеет только одинAppDomain?

Ответы [ 3 ]

4 голосов
/ 23 июля 2010

Среда выполнения Asp.Net хранит пул объектов HttpApplication.Каждый запрос .aspx обрабатывается одним объектом, который выделяется из пула (8 объектов в вашем случае).

Ответ на ваш вопрос, событие Application_Start действительно вызывается, но только для первого экземпляраHttpApplication, а не последующие, поэтому вы можете быть уверены, что он вызывается ровно один раз при запуске приложения или при перезапуске пула приложений IIS.Как и событие Application_OnEnd (последний экземпляр)

, между тем, Init () и Dispose () вызываются для каждого экземпляра объекта HttpApplication.Это будет вызываться для каждого экземпляра, иначе для каждого запроса.

Почему они делают это таким образом? ..возможно, чтобы сбалансировать производительность и оптимизацию памяти.

Надеюсь, я ответил на ваш вопрос.

3 голосов
/ 31 мая 2011

Вызов Application_Start в первый раз, когда создается экземпляр HttpApplication, но не в последующих экземплярах, кажется чем-то взломанным. Возможно, Microsoft не хотела объяснять концепцию статического конструктора людям, которые не хотели этого знать.

Application_End (), однако, представляется необходимостью, поскольку в C # нет эквивалента статического деструктора / финализатора. Как взломать, это не так уж плохо. Просто пахнет немного смешно.

0 голосов
/ 23 июля 2010

Для каждого одновременного запроса создается один объект HttpApplication.То есть каждый поток, который создает ASP.NET, получает свой собственный экземпляр HttpApplication.Экземпляры повторно используются для последующих запросов так же, как потоки повторно используются из пула потоков.

Используйте метод Init для инициализации полей экземпляра в приложении HttpApplication, поскольку они будут инициализированы только в первом экземпляреесли это сделано в событии Application_Start.

...