|
私のように多くの友人が、アプリケーション初期化操作を行うためにIHttpModule.InitをApplication_Start代替として誤って使ってしまったことに気づきました。 しかし、IHttpModule.InitとGlobal.asaxのApplication_Startイベントの性質は異なり、IHttpModule.Initはアプリケーションの初期化プロセスを直接置き換えApplication_Start ASP.NET ことはできません。 また、単にInitメソッドが繰り返し呼び出されてプログラムが再起動されたと結論づける ASP.NET だけでもありません。 その理由は、IHttpModule.Initがリクエスト ASP.NET に応答する際に複数回呼び出されることがあり、実際のウェブサイト運用中に起こる可能性が非常に高いためです。 なぜIHttpModule.Initが複数回呼び出されるのか?なぜなら、各HttpApplicationインスタンスは同時に1つのリクエストしか処理できず、ASP.NET 一定数の同時リクエストをサポートしているため、HttpApplicationインスタンスは同時リクエストに対応できない場合に複数回作成されるからです。 各HttpApplicationインスタンスは新しいHttpModuleのセットを作成し、作成後にInitメソッドを呼び出します。 Application_Startは最初のHttpApplicationオブジェクトが作成された後にのみ呼び出され、その後のHttpApplicationインスタンスではこのイベントは発生しません。 HttpApplicationインスタンスの再利用がIHttpModuleのInitメソッドの使用誤解の主な原因だと思います。なぜなら、プログラムのデバッグ時に通常リクエストは1つだけで、HttpModuleのInitメソッドを繰り返し実行するのはほぼ不可能だからです。 実際のウェブサイト実行環境では、同時要求が一般的であり、Initメソッドが誤用されると、実際の環境で奇妙な問題を引き起こす可能性があります。 詳細については、記事内の画像が掲載されているMSDNの「IIS 5.0および6.0の ASP.NET アプリケーションライフサイクル概要」をご参照ください。 また、Refelectorを使ってSystem.Webアセンブリをデコンパイルし、IHttpModule.Initメソッドの呼び出し関係を解析することもできます。 最終的にSystem.Web.HttpApplicationFactory.GetNormalApplicationInstanceメソッドができ、HttpApplicationのインスタンスがどのように再利用・作成されるかを示します。 まとめると、IHttpModule.initは単にApplication_Startの代替として使うことはできません。 比較的簡単な方法としては、静的なブール型フィールドを初期化タグとして使い、HttpModuleでプログラムが要求する初期化後にマークをtrueに設定し、次回は初期化を繰り返さないことです。 しかし、BeginRequestイベントの登録のようなコードは、Initが実行されるたびに毎回実行する必要があります。なぜなら、この時点でのHttpModuleインスタンスが異なるためです。登録イベントを繰り返さずに静的初期化マークアップフィールドを判断すると、URLの書き換えが実行される場合もあれば、実行されない場合もあるという奇妙な問題が生じます。
[神話]HttpApplication オブジェクト Init メソッドは一度だけ実行されるのでしょうか?
回答:複数回実行されます!!!!
|