|
Открих, че много приятели, като мен, погрешно използваха IHttpModule.Init като Application_Start алтернатива за извършване на някои операции за инициализация на приложения в него. Въпреки това, природата на Application_Start събития в IHttpModule.Init и Global.asax е различна и IHttpModule.Init не може да се използва директно за замяна Application_Start ASP.NET процеса на инициализация на приложението. Нито може просто да се използва, за да се заключи, че методът на Init се повтаря и се заключава, че ASP.NET програма е рестартирана. Причината е, че IHttpModule.Init може да бъде извикан многократно при отговор на заявка ASP.NET и е много вероятно да се случи по време на самата работа на уебсайта. Защо IHttpModule.Init се извиква многократно, защото всяка HttpApplication инстанция може да обработва само една заявка наведнъж и ASP.NET поддържа определен брой едновременни заявки, така че HttpApplication instance ще бъде създаван многократно, за да отговаря на различни заявки, когато това не е достатъчно за отговор на едновременни заявки. Всяка HttpApplication инстанция създава нов набор от HttpModules и извиква Init метода след като бъде създаден. Application_Start ще бъде извикан едва след като първият HttpApplication обект бъде създаден, а следващите HttpApplication инстанции няма да задействат това събитие. Мисля, че повторната употреба на HttpApplication инстанции е основна причина за неразбирането на метода Init на IHttpModule, защото обикновено имаме само една заявка при дебъгване на програма, и е практически невъзможно многократно да се изпълнява методът Init на HttpModule. В действителната среда на работещ уебсайт едновременните заявки са често срещани и ако методът Init се използва неправилно, това може да причини странни проблеми в самата среда. За конкретни подробности, моля, вижте MSDN "Преглед на жизнения цикъл на ASP.NET приложения за IIS 5.0 и 6.0", който предоставя изображения в статията: Можете също да използвате Refelector за декомпилиране на System.Web асемблера и анализ на връзката на извикване на метода IHttpModule.Init. Ще получите метода System.Web.HttpApplicationFactory.GetNormalApplicationInstance, който показва как се използват и създават инстанции на HttpApplication. В обобщение, IHttpModule.Init не може просто да се използва като заместител на Application_Start. Сравнително прост начин е да се използва статично поле тип bool като таг за инициализация, да се зададе марката на true след инициализацията, изисквана от програмата в HttpModule, и да не се повтаря инициализацията следващия път. Въпреки това, код като регистрация на събитието BeginRequest все пак трябва да се изпълнява всеки път, когато се изпълнява Init, защото инстанцията на HttpModule в момента е различна; ако прецените статичното поле за инициализация без да повтаряте регистрационното събитие, това ще доведе до странни проблеми като пренаписване на URL адреси, понякога изпълнено, понякога не.
[Мит] Ще се изпълнява ли методът Init на обекта Init в HttpApplication само веднъж?
Отговор: Ще бъде изпълнено многократно!!!!
|