|
Jeg oppdaget at mange venner, som meg, feilaktig brukte IHttpModule.Init som et Application_Start alternativ for å gjøre noen applikasjonsinitialiseringsoperasjoner i den. Imidlertid er naturen til Application_Start hendelser i IHttpModule.Init og Global.asax forskjellig, og IHttpModule.Init kan ikke brukes direkte til å erstatte Application_Start ASP.NET initialiseringsprosessen i applikasjonen. Den kan heller ikke bare brukes til å konkludere med at Init-metoden gjentatte ganger kalles for å konkludere med at ASP.NET programmet har blitt startet på nytt. Grunnen er at IHttpModule.Init kan bli kalt flere ganger når man svarer på en forespørsel ASP.NET, og det er svært sannsynlig at det skjer under selve nettstedets drift. Hvorfor blir IHttpModule.Init kalt flere ganger? Fordi hver HttpApplication-instans bare kan håndtere én forespørsel om gangen, og ASP.NET støtter et visst antall samtidige forespørsler, så HttpApplication-instansen vil bli opprettet flere ganger for å svare på ulike forespørsler når det ikke er nok til å svare på samtidige forespørsler. Hver HttpApplication-instans oppretter et nytt sett med HttpModules og kaller Init-metoden etter at den er opprettet. Application_Start vil kun bli kalt etter at det første HttpApplication-objektet er opprettet, og påfølgende HttpApplication-instanser vil ikke utløse denne hendelsen. Jeg tror gjenbruk av HttpApplication-instanser er en hovedårsak til misforståelsen av bruken av IHttpModules Init-metode, fordi vi vanligvis bare har én forespørsel når vi feilsøker et program, og det er i praksis umulig å gjentatte ganger kjøre HttpModules Init-metode. I selve nettsidekjøringsmiljøet er samtidige forespørsler vanlige, og hvis Init-metoden misbrukes, kan det føre til merkelige problemer i selve miljøet. For spesifikke detaljer, se MSDNs «Oversikt over ASP.NET applikasjonslivssyklus for IIS 5.0 og 6.0», som gir bilder i artikkelen: Du kan også bruke Refelector til å dekompilere System.Web-assembleren og analysere kallrelasjonen til IHttpModule.Init-metoden. Du ender opp med metoden System.Web.HttpApplicationFactory.GetNormalApplicationInstance, som viser hvordan instanser av HttpApplication gjenbrukes og opprettes. Oppsummert kan ikke IHttpModule.Init bare brukes som erstatning for Application_Start. En relativt enkel måte er å bruke et statisk bool-type felt som initialiseringstagg, og sette merket til true etter initialiseringen som kreves av programmet i HttpModule, og ikke gjenta initialiseringen neste gang. Men kode som registrering av BeginRequest-hendelsen må fortsatt utføres hver gang Init kjøres, fordi HttpModule-instansen på dette tidspunktet er annerledes; hvis du vurderer det statiske initialiseringsmarkup-feltet uten å gjenta registreringshendelsen, vil det føre til merkelige problemer som URL-omskriving, noen ganger utført og noen ganger ikke.
[Myte] Vil HttpApplication-objektet Init-metoden bare bli kjørt én gang?
Svar: Den vil bli utført flere ganger!!!!
|