8

12 年ほど前に古典的な ASP のプログラミングを始めて以来、私はこれを繰り返してきましたが、ASP と ASP.NET のアーキテクチャは常に悪い慣行の沼地であり、魔法が共有されていたため、優れた解決策を見つけたことはありませんでした。シングルトンなど。私の最大の問題は、HttpApplicationイベント以外のイベント( 、など)を持つオブジェクトにApplication_StartありApplication_Endます。

HTTP アプリケーションの存続期間全体で 1 回だけ何かを実行したい場合は、それを実行するのに最適Application_Startな場所です。右?ではない正確に。まず、これはイベント自体ではなく、IIS によって作成された AppDomain ごとに 1 回メソッドが呼び出される魔法の命名規則です。

魔法の命名規則が恐ろしい慣習であることに加えて、オブジェクトにStartイベントのようなものが存在しない理由かもしれないと私は考え始めました。HttpApplicationそのため、 などの存在するイベントを試してみましたInit。これも実際にはイベントではなく、オーバーライド可能なメソッドであり、次善の策です。

このメソッドは、AppDomain ごとに複数回発生するInit()、オブジェクトのインスタンス化ごとに呼び出されるようです。これは、起動ロジックをオブジェクトのコンストラクターHttpApplication内に配置するだけでよいことを意味します。HttpApplication

ここで私の質問は、起動ロジックをコンストラクターに入れるべきではないのはなぜですか? なぜさえInit()存在し、私は気にする必要がありApplication_Startますか? HttpApplicationもしそうなら、オブジェクトのこの疑似イベントに適切なイベントまたはオーバーライド可能なメソッドがない理由を誰か説明できますか?

そして、典型的なASP.NETアプリケーションで、myの8つのインスタンスが作成される理由を誰でも説明できますかHttpApplication(これにより、コンストラクターとInitが同じ回数実行されます。これは、ロックと共有静的ブール値で軽減できますinitialized)アプリケーションに AppDomain が 1 つしかない場合

4

3 に答える 3

5

Asp.Net ランタイムは、HttpApplication オブジェクトのプールを保持します。すべての .aspx 要求は、プールから割り当てられた単一のオブジェクト (この場合は 8 つのオブジェクト) によって処理されます。

あなたの質問に対する答え、Application_Start イベントは実際に呼び出されますが、HttpApplication の最初のインスタンスに対してのみ呼び出され、後続のインスタンスに対しては呼び出されないため、アプリケーションが開始されるか、IIS のアプリケーション プールが再起動されるたびに、正確に 1 回呼び出されることを確認できます。 . Application_OnEnd イベント (最後のインスタンス) も同様です。

一方、Init() と Dispose() は、HttpApplication オブジェクトのすべてのインスタンスで呼び出されます。これは、各インスタンス、つまり各リクエストで呼び出されます。

なぜ彼らはそのようにするのですか..?おそらく、パフォーマンスとメモリの最適化のバランスを取るためです。

あなたの質問に答えていただければ幸いです。

于 2010-07-23T13:06:18.040 に答える
3

HttpApplication のインスタンスが初めて作成されたときに Application_Start を呼び出すが、後続のインスタンスでは呼び出さないのは、ちょっとしたハックのようです。おそらく、Microsoft は静的コンストラクターの概念を知りたくない人に説明したくなかったのでしょう。

ただし、静的デストラクタ/ファイナライザに相当する C# がないため、Application_End() は必須のようです。ハッキングが進むにつれて、これはそれほど悪くはありません。ちょっと面白い匂いがします。

于 2011-05-31T02:13:34.057 に答える
0

同時リクエストごとに1つのHttpApplicationオブジェクトが作成されます。つまり、ASP.NETが作成する各スレッドは、独自のHttpApplicationのインスタンスを取得します。インスタンスは、スレッドがスレッドプールから再利用されるのと同じ方法で、後続のリクエストに再利用されます。

Initメソッドを使用して、HttpApplicationのインスタンスフィールドを初期化します。これらは、Application_Startイベントで実行された場合、最初のインスタンスでのみ初期化されるためです。

于 2010-07-23T12:39:00.823 に答える