Дополнительно: Сколько раз метод HttpModule Init () вызывается в течение жизни приложения? - PullRequest
26 голосов
/ 30 июля 2010

Инициализация веб-приложения выглядит следующим образом:

  1. Как известно, когда IIS получает первый запрос для определенного ресурса приложения Asp.net, IIS создает экземпляр HttpApplication (определенный в global.asax codebehind).
  2. Когда создается этот новый экземпляр, происходит его инициализация, который также проверяет все настроенные модули HTTP.
  3. Затем создаются все модули и помещаются в коллекцию Modules приложения (изtype HttpModuleCollection)
  4. модули проходят через цикл и вызывается их метод Init() (когда они регистрируются для событий запроса)

Насколько я понимаю, вышеописанный сценарий происходиткогда веб-приложение запускается / инициализируется (следовательно, событие запуска приложения).

Что происходит с модулями?

Они (повторно) устанавливаются при каждом запросе или повторно используются из свойства Modules вкаждый последующий запрос, пока веб-приложение живо?Насколько я понимаю, IIS и Asp.net повторно используются в течение всей жизни веб-приложения.

Если они используются повторно, можем ли мы предположить, что их метод Init() на самом деле является обработчиком псевдо-события для события запуска приложения?Дело в том, что мы не можем присоединиться к событиям уровня приложения в модулях http.Но если они используются повторно, мы могли бы использовать Init() в качестве события запуска приложения и делать все, что вместо этого мы добавили бы global.asax.

Вопрос

Можем ли мы предположить, что Init() этого модуляметод называется только в случае запуска приложения?Можем ли мы использовать это предположение, чтобы зарегистрировать маршруты для приложений, код которых global.asax не может быть изменен?web.config обычно доступен, и мы можем изменить его так, как мы хотим.
Это действительно сработает?

Дополнительная информация

Мы можем проверить HttpApplicationкод и проверьте его InitModulesCommon() метод.Этот на самом деле вызывает Init() каждого зарегистрированного модуля HTTP.Что более интересно, этот метод используется только методами InitIntegratedModules() и InitModules().Которые оба используются только в HttpApplication.InitInternal() методе.Это основа моих предположений, но я хотел бы знать, не злоупотребил ли кто-то IHttpModule.Init() событием запуска приложения.

Ответы [ 2 ]

31 голосов
/ 31 июля 2010

Init() вызывается только один раз (для HttpApplication экземпляра)

После того, как я проверил это, внутренняя работа инициализации IHttpModule выглядит следующим образом:

  1. Каждое IHttpModule инициализируется при запуске веб-приложения путем вызова и вызова Init() метода
  2. HttpApplication сохраняет все экземпляры модуля в свойстве Modules
  3. Модули затем повторно используются в течение всего срока службы HttpApplication и не удаляются / реинициализируются до тех пор, пока приложение работает

Итак, лучший результат -

Вы не можете присоединить IHttpModule к событиям уровня приложения, но вы можете использовать его метод Init() в качестве делегата события запуска псевдо-приложения . Внутри него вы можете выполнить любой код, который вы обычно помещаете в делегат Application_Start в вашем Global.asax.

Подробную информацию об этом вы также можете прочитать в моем блоге .

Но будьте осторожны в реальной среде веб-сервера

Но IIS использует то, что называется пулы приложений . И каждый пул может иметь произвольное количество HttpApplication экземпляров. Да несколько. Запуск приложения создает все эти экземпляры. Каждый из них инициализирует свой список модулей, но только первый выполняет обработчик события Application_OnStart.

Таким образом, всякий раз, когда ваш модуль модифицирует какой-либо общий общий ресурс, вы должны принять дополнительные меры, чтобы указать, что первый модуль сделал это, а другие не будут делать это снова. Прочтите дополнительную запись в блоге о ней, которая покажет вам, как и когда использовать блокировку потоков с вашим модулем, чтобы он действовал как обработчик событий Application_OnStart. Кстати, также возможно обработать событие Application_OnEnd, если вам нужно. ;)

Подробные ссылки на посты в блоге

  1. Написание собственного IHttpModule, который обрабатывает событие Application_OnStart
  2. Как правильно использовать IHttpModule для обработки события Application_OnStart
3 голосов
/ 30 июля 2010

Application_Start запускается только один раз за время существования вашего приложения.

IHttpModule.Init запускается для каждого экземпляра HttpApplication перед началом обработки запроса. См. прохождение . Init - это место, где вы можете зарегистрировать события, используемые для обработки запроса.

Экземпляр HttpApplication может быть повторно использован для нескольких запросов. ASP.Net объединяет объекты HttpApplication, поэтому Init будет вызываться один раз для каждого нового экземпляра HttpApplication

...