|
Zistil som, že mnohí priatelia, rovnako ako ja, omylom používali IHttpModule.Init ako Application_Start alternatívu na inicializačné operácie aplikácie. Povaha Application_Start udalostí v IHttpModule.Init a Global.asax je však odlišná a IHttpModule.Init sa nedá použiť priamo na nahradenie Application_Start ASP.NET inicializačného procesu aplikácie. Ani sa nedá jednoducho použiť na záver, že metóda Init je opakovane volaná na záver, že ASP.NET program bol reštartovaný. Dôvodom je, že IHttpModule.Init môže byť volaný viackrát pri odpovedi na požiadavku ASP.NET a je veľmi pravdepodobné, že sa to stane počas samotnej prevádzky webu. Prečo je IHttpModule.Init volaný viackrát, pretože každá inštancia HttpApplication dokáže naraz spracovať len jednu požiadavku a ASP.NET podporuje určitý počet súbežných požiadaviek, takže inštancia HttpApplication sa vytvorí viackrát, aby odpovedala na rôzne požiadavky, keď to nestačí na súčasné požiadavky. Každá inštancia HttpApplication vytvorí novú sadu HttpModules a po vytvorení volá metódu Init. Application_Start bude volaná až po vytvorení prvého objektu HttpApplication a nasledujúce inštancie HttpApplication túto udalosť nevyvolajú. Myslím si, že opätovné použitie inštancií HttpApplication je hlavným dôvodom nepochopenia použitia metódy Init v IHttpModule, pretože pri ladení programu zvyčajne máme len jednu požiadavku a je prakticky nemožné opakovane vykonávať metódu Init v HttpModule. V skutočnom prostredí bežiacom webe sú bežné súbežné požiadavky, a ak sa metóda Init zneužije, môže to spôsobiť zvláštne problémy v reálnom prostredí. Pre konkrétne podrobnosti si pozrite MSDN "Prehľad životného cyklu ASP.NET aplikácií pre IIS 5.0 a 6.0", ktorý obsahuje obrázky v článku: Môžete tiež použiť Refelector na dekompiláciu asembléru System.Web a analýzu vzťahu volania metódy IHttpModule.Init. Nakoniec dostanete metódu System.Web.HttpApplicationFactory.GetNormalApplicationInstance, ktorá ukazuje, ako sa inštancie HttpApplication opakovane používajú a vytvárajú. Na záver, IHttpModule.Init nemožno jednoducho použiť ako náhradu za Application_Start. Relatívne jednoduchý spôsob je použiť statické pole typu bool ako inicializačný tag a nastaviť mark na true po inicializácii požadovanej programom v HttpModule a nabudúce inicializáciu neopakovať. Avšak kód ako registrácia udalosti BeginRequest sa musí vykonávať zakaždým, keď sa spustí Init, pretože inštancia HttpModule je v tomto čase iná; ak hodnotíte statické pole inicializačného označovania bez opakovania registračnej udalosti, povedie to k zvláštnym problémom, ako je prepísanie URL niekedy vykonané a niekedy nie.
[Mýtus] Bude metóda Init objektu HttpApplication vykonaná iba raz?
Odpoveď: Bude vykonaný viackrát!!!!
|