|
Huomasin, että monet ystävät, kuten minäkin, käyttivät virheellisesti IHttpModule.Initia Application_Start vaihtoehtona joidenkin sovellusalustusoperaatioiden tekemiseen siinä. Kuitenkin Application_Start tapahtumien luonne IHttpModule.Initissä ja Global.asaxissa on erilainen, eikä IHttpModule.Initia voi käyttää suoraan korvaamaan Application_Start ASP.NET sovelluksen alustusprosessia. Eikä sitä voi käyttää pelkästään päätelläkseen, että Init-menetelmää kutsutaan toistuvasti päättelemään, että ASP.NET ohjelma on käynnistetty uudelleen. Syynä on se, että IHttpModule.Init voidaan kutsua useita kertoja vastattaessa pyyntöön ASP.NET, ja se tapahtuu hyvin todennäköisesti varsinaisen verkkosivuston toiminnan aikana. Miksi IHttpModule.Init kutsutaan useita kertoja, koska jokainen HttpApplication-instanssi pystyy käsittelemään vain yhtä pyyntöä kerrallaan, ja ASP.NET tukee tiettyä määrää samanaikaisia pyyntöjä, joten HttpApplication-instanssi luodaan useita kertoja vastaamaan eri pyyntöihin, kun se ei riitä vastaamaan samanaikaisiin pyyntöihin. Jokainen HttpApplication-instanssi luo uuden joukon HttpModuleja ja kutsuu Init-metodia sen luomisen jälkeen. Application_Start kutsutaan vasta ensimmäisen HttpApplication-objektin luomisen jälkeen, eikä myöhemmät HttpApplication-instanssit laukaise tätä tapahtumaa. Uskon, että HttpApplication-instanssien uudelleenkäyttö on merkittävä syy IHttpModulen Init-metodin väärinymmärrykseen, koska meillä on yleensä vain yksi pyyntö ohjelman virheenkorjauksessa, ja HttpModulen Init-metodia on käytännössä mahdotonta suorittaa toistuvasti. Varsinaisessa verkkosivuston ajoympäristössä samanaikaiset pyynnöt ovat yleisiä, ja jos Init-menetelmää käytetään väärin, se voi aiheuttaa outoja ongelmia varsinaisessa ympäristössä. Tarkempia tietoja löytyy MSDN:n artikkelista "Overview of the ASP.NET Application Lifecycle for IIS 5.0 and 6.0", joka sisältää kuvia artikkelissa: Voit myös käyttää Refelectoria System.Web-kokoonpanon purkamiseen ja IHttpModule.Init-metodin kutsusuhteen analysointiin. Lopulta saat System.Web.HttpApplicationFactory.GetNormalApplicationInstance-metodin, joka näyttää, miten HttpApplication-instansseja käytetään uudelleen ja luodaan. Yhteenvetona voidaan todeta, että IHttpModule.Init ei yksinkertaisesti toimi Application_Start:n korvaajana. Melko yksinkertainen tapa on käyttää staattista bool-tyyppistä kenttää alustustunnisteena ja asettaa merkki tosiksi ohjelman vaatiman alustuksen jälkeen HttpModulessa, eikä toista alustusta seuraavalla kerralla. Kuitenkin koodi, kuten BeginRequest-tapahtuman rekisteröinti, täytyy silti suorittaa joka kerta kun Init suoritetaan, koska HttpModule-instanssi on tällä hetkellä erilainen. Jos tarkastelet staattista alustusmerkkikenttää toistamatta rekisteröintitapahtumaa, se johtaa outoihin ongelmiin, kuten URL-osoitteiden uudelleenkirjoittamiseen, joskus suoritettuihin ja joskus suorittamatta.
[Myytti] Suoritetaanko HttpApplication-objektin Init-metodi vain kerran?
Vastaus: Se suoritetaan useita kertoja!!!!
|