|
Zjistil jsem, že mnoho přátel, stejně jako já, omylem používalo IHttpModule.Init jako Application_Start alternativu k provádění inicializačních operací aplikací. Povaha Application_Start událostí v IHttpModule.Init a Global.asax je však odlišná a IHttpModule.Init nelze použít přímo jako náhradu Application_Start ASP.NET procesu inicializace aplikace. Nelze ji ani jednoduše použít k závěru, že metoda Init je opakovaně vyvolávána k závěru, že ASP.NET program byl restartován. Důvodem je, že IHttpModule.Init může být při odpovědi na požadavek ASP.NET vyvolán vícekrát, a je velmi pravděpodobné, že k tomu dojde během samotného provozu webu. Proč je IHttpModule.Init volán opakovaně, protože každá instance HttpApplication může zpracovat pouze jeden požadavek najednou a ASP.NET podporuje určitý počet současných požadavků, takže instance HttpApplication bude vytvořena opakovaně, aby odpovídala na různé požadavky, když to nestačí na současné požadavky. Každá instance HttpApplication vytváří novou sadu HttpModules a po vytvoření volá metodu Init. Application_Start bude volán až po vytvoření prvního objektu HttpApplication a následující instance HttpApplication tuto událost nespouštějí. Myslím, že opětovné použití instancí HttpApplication je hlavním důvodem nepochopení použití metody Init v IHttpModule, protože při ladění programu obvykle máme jen jeden požadavek a je prakticky nemožné opakovaně spouštět metodu Init v HttpModule. V reálném prostředí běžícího webu jsou běžné souběžné požadavky, a pokud je metoda Init zneužita, může to způsobit zvláštní problémy v reálném prostředí. Pro konkrétní podrobnosti prosím navštivte MSDN "Přehled životního cyklu ASP.NET aplikací pro IIS 5.0 a 6.0", který obsahuje obrázky v článku: Můžete také použít Refelector k dekompilaci asembléru System.Web a analýze vztahu volání metody IHttpModule.Init. Nakonec získáte metodu System.Web.HttpApplicationFactory.GetNormalApplicationInstance, která ukazuje, jak jsou instance HttpApplication znovu používány a vytvářeny. Shrnuto, IHttpModule.Init nelze jednoduše použít jako náhradu za Application_Start. Relativně jednoduchý způsob je použít statické pole typu bool jako inicializační tag a nastavit mark na true po inicializaci požadované programem v HttpModule, a příště inicializaci neopakovat. Nicméně kód jako registrace události BeginRequest musí být stále vykonán při každém spuštění Init, protože instance HttpModule je v tuto chvíli jiná – pokud hodnotíte statické pole pro označování inicializace bez opakování registrační události, povede to k podivným problémům, jako je přepsání URL někdy provedeno a jindy ne.
[Mýtus] Bude metoda Init objektu HttpApplication vykonána pouze jednou?
Odpověď: Bude provedena opakovaně!!!!
|