Application オブジェクト  

ASP (Active Server Pages : アクティブサーバーページ) のコンテキストでは、アプリケーションは、指定された仮想ディレクトリおよびそのサブディレクトリを経由してアクセスできるすべてのファイルの合計です。この ASP アプリケーションコンテキストは、アプリケーションを使用しているすべてのクライアントに対して同一です。たとえば、"/SearchApp" 仮想ディレクトリのページを要求するタイ在住のクライアントは、同じ仮想ディレクトリのページを要求している別のスウェーデン在住のクライアントと同一の "アプリケーション" にアクセスすることになります。これは、各クライアントが要求する仮想ディレクトリ内の特定の Web ページには無関係です。

従来のスタンドアロンアプリケーションと同様、ASP アプリケーションもアプリケーション全体で情報を共有できます。Application オブジェクトを使用している、指定した ASP アプリケーションのすべてのクライアント間で情報を共有することができます。この組み込みオブジェクトは、ASP アプリケーション自体を表し、アプリケーションにアクセスしているクライアントの数やタイプ、それらのクライアントが要求しているアプリケーションの部分に関係なく同じのものです。

Application オブジェクトは、最初のクライアントから指定された仮想ディレクトリ内の任意のファイルが要求されるとすぐに、IIS によって初期化されます。この Application オブジェクトは、Web サービスを停止するか、Microsoft 管理コンソール (Microsoft Management Console) を使用してアプリケーションを Web サーバーから明示的にアンロードするまで、サーバーのメモリ内に残ります。

IIS では、アプリケーションレベルのスコープを使用して変数とオブジェクトをインスタンス化できます。つまり、指定された変数は、アプリケーションのすべてのクライアントに対して同じ値を保持します。また、すべてのクライアントに対して同じ値を保持するサーバー側のオブジェクトを、アプリケーションレベルのスコープを使用してインスタンス化できます。これらのアプリケーションレベルの変数とオブジェクトには、任意のユーザーセッションのコンテキストと現在のアプリケーション内の任意のファイルからアクセスして変更できます。

前述のとおり、Application オブジェクトの 初期化は、アプリケーションの最初のユーザーが ASP アプリケーションに含まれる仮想ディレクトリ内のファイルを要求したときに発生します。この初期化は、指定された ASP アプリケーション用に予約されたメモリと考えられます。Web サーバーは、Application オブジェクトをインスタンス化し初期化します。ただし、"GLOBAL.ASA" と呼ばれる特別なオプションファイル内にコードを記述することにより、この初期化をカスタマイズできます。 このファイルの詳細については第 11 章で説明しますが、ここでは概略を簡単に説明します。

"GLOBAL.ASA" ファイルが存在するのは、それが ASP アプリケーションの仮想ディレクトリによってマップされた物理ディレクトリのルートにある場合です。このファイルは、新規のユーザーがアプリケーションの仮想ディレクトリ内のページを要求するたびに処理されます。このファイルには、ユーザーセッションとアプリケーション自体の両方の初期化コードが含まれています。ユーザーが初めてのユーザーでない場合、"GLOBAL.ASA" のアプリケーション固有のセクションは処理されません。"GLOBAL.ASA" ファイルが存在しないかこのファイルにコードが含まれず、ユーザーの要求が指定されたアプリケーション内のファイルに対する Web サーバーの最初の要求である場合も、Web サーバーは Application オブジェクトを初期化します。ただし、Web サーバーの初期化にはアプリケーションに必要なメモリのサイズのみが関係します。

"GLOBAL.ASA" ファイルには、アプリケーションレベルのスコープを持つ変数とオブジェクトを作成する場所が用意されています。"GLOBAL.ASA" ファイルのこのセクションは、イベントプロシージャを表します。このイベントは OnStart イベントであり、そのイベントハンドラはアプリケーションを起動すると実行されます。"GLOBAL.ASA" ファイルは要求するすべてのユーザーに対して処理されますが、Application オブジェクトの OnStart イベントは最初のユーザーのみに対して実行されることに注意してください。OnStart イベントプロシージャと、対応する OnEnd イベントプロシージャの詳細については、本章の後の部分で説明します。

アプリケーションレベルのスコープを使用した変数とオブジェクトは、アプリケーションの継続期間中、すべてのユーザーに対して同じ値となります。1 人のユーザーが、アプリケーションレベルの変数の値を変更するコードを含むページを要求すると、その変数の値はすべてのユーザーに対して変更されます。これにより、次のような問題が生じます。つまり、複数のユーザーが、同時に同じアプリケーションレベル変数の変更を試みる可能性があります。幸い、この状況における競合の問題を避けるために、ASP では Application オブジェクトの Lock メソッドおよび Unlock メソッドを利用できます。マルチスレッドアプリケーションに含まれるグローバル変数の使用に関する問題を考慮する必要があるのと同様に、アプリケーションレベルのスコープを使用した変数の使用に関する問題についても考慮する必要があります。アプリケーションレベルの変数の使用には注意が必要です。

ASP Application オブジェクトのプロパティ、コレクション、メソッド、およびイベントの概略については、「Application オブジェクトの概要」を参照してください。

コメントおよびトラブルシューティング  
 
 

アプリケーションレベルの変数とは、実際上は ASP アプリケーションのグローバル変数のことです。ASP アプリケーションにおけるグローバル変数の使用については、従来のスタンドアロンアプリケーションにおけるグローバル変数の使用と同じくらい、またはそれ以上に慎重に考える必要があります。最も重要なステップは、アプリケーションレベルのスコープを使用したオブジェクトまたは変数を実装する前に、そのスコープを慎重に検討することです。これらの ASP グローバル変数の使用が必要な例はほとんどありません。

このような注意とは別に、アプリケーションレベルの変数またはオブジェクトの使用が、機能的な ASP アプリケーションを作成する際に役立ついくつかの例があります。最も重要な例の 1 つとして、Web サイトについてアプリケーション固有の統計情報を管理することがあります。たとえば、ユーザーセッションが開始するたびに増分されるアプリケーションレベルの変数を使用して、アプリケーションを使用中のクライアントの数を管理することもできます。Microsoft Site Server などの Web 管理ツールも同様のタスクを実行しますが、それらの統計情報はアプリケーション固有ではなくファイル固有のものです。

一部の ASP 資料では、アプリケーションレベルのオブジェクトを使用して、すべてのアプリケーションユーザーに対して開かれた ActiveX Data Objects (ADO) データベース接続を管理することを推奨しています。ADO の詳細については、第 12 章を参照してください。これは、アプリケーションレベルの変数の使用方法としては推奨されません。この方法により、ODBC (Open Database Connectivity) はページごとに接続をプールすることができなくなるからです。ただし、アプリケーションレベルの変数を使用すると、同じデータベース接続に対するアプリケーション固有の接続文字列を管理できます。

ODBC 接続プールには、連続するユーザーが ODBC 接続を再利用できるメソッドが用意されています。サーバーでは、クライアントが要求するたびに新しい接続を作成する代わりに、既に存在していて未使用になった接続の再利用を試みます。未使用の ODBC 接続が MMC で構成された特定期間の経過後にメモリ内にある場合は、その接続は削除されてメモリが開放されます。

アプリケーションレベルの変数およびオブジェクトの使用を検討する場合、注意しなければならない問題が 1 つあります。例を次に示します。"c:\inetpub\wwwroot\MainApp" と "c:\inetpub\wwwroot\MainApp\SearchApp" の 2 つの物理ディレクトリがあるとします。これらのディレクトリは、仮想ディレクトリ "/MainApp" と "/SearchApp" にそれぞれマップされます。実際上、アプリケーション内にアプリケーションがあることになります。最初のクライアントが、"c:\inetpub\wwwroot\MainApp\SearchApp" 物理ディレクトリ内のページを要求します。Application オブジェクトを初期化するために、"/MainApp" の "GLOBAL.ASA" または "/SearchApp" の "GLOBAL.ASA" のいずれの初期化コードが使用されるでしょうか。この場合、"/SearchApp" の "GLOBAL.ASA" が処理されます。"/SearchApp" に存在しない "/MainApp " のファイルが要求されるまで、"/MainApp" の "GLOBAL.ASA" ファイルは処理されません。2 つの "GLOBAL.ASA" ファイルで異なる一連のアプリケーションレベル変数を定義する場合、テストなしで Application 変数が適切に初期化されたことをコード内で知る方法はありません。

最後に、現在 IIS では、Microsoft 管理コンソール (Microsoft Management Console) の特定の仮想ディレクトリのプロパティパネル上でオプションを指定するだけで、相互に異なるメモリスペース、または Web サーバー自体とは別のメモリスペースに ASP アプリケーションを設定できます。この機能は IIS の重要な改良点です。ASP アプリケーションが Web サーバーとは別のメモリスペースで実行され、その中に含まれるサーバーオブジェクト (またはスクリプトエンジン自体) がクラッシュする場合、Web サーバーまたは他の ASP アプリケーションはクラッシュしません。

Contents コレクション  
Application.Contents.Item("Pi") = 3.14
 

Application オブジェクトの Contents コレクションには、<OBJECT> タグの使用によってではなく、スクリプトの使用によって現在のアプリケーションに追加されるすべてのアプリケーションレベルのスコープの変数とオブジェクトが含まれます。

Contents コレクションに要素を追加する方法を確認する前に、まず Contents コレクションのプロパティを理解する必要があります。Contents コレクションには以下に示す 3 つのプロパティがあります。

Item

Contents コレクションの特定のメンバーの値を取得します。文字列キーを使用するメンバー (Key プロパティによるインデックスを使用して値を入手できるメンバー、詳細は本項の後の部分で説明)、またはインデックス番号を使用するメンバーを指定します。たとえば、Contents コレクションに含まれる要素を Pi の値を使用して初期化する場合、次のような一連のコードを使用できます。

Application.Contents.Item("Pi") = 3.14

前のコード行では、コレクションに含まれる目的の要素は、キー値 "Pi" を使用して指定します。このように初期化すると、次のコード行を使用して、Contents コレクションのこの要素の値を取得できます。

dblMyVar = Application.Contents.Item("Pi")

すぐに明らかになることですが、これが Contents コレクションに追加される最初の要素であるとします。

次のコード行が示すように、キーではなく、コレクションに含まれるインデックスを使用しても、Contents コレクションに含まれる要素の値を取得できます。

dblMyVar = Application.Contents.Item(1)

Contents コレクションに含まれる最初の要素を表すには、0 ではなく 1 を使用します。このコード行で 0 を使用すると、変数 dblMyVar が未定義の値で初期化されるため、これは微妙なポイントです。残念ながら、これによりエラーは発生しません。結果として、変数が不適切に初期化されるだけです。

dblMyVar = Application.Contents.Item(0) ' WRONG.

Item は Contents コレクションのデフォルトのプロパティであり、Contents コレクションは Application オブジェクトのデフォルトのコレクションです。つまり、次の 3 行のコードは、アプリケーションでまったく同じ方法で解釈されます。

Application.Contents.Item("Pi") = 3.14
Application.Contents("Pi") = 3.14
Application("Pi") = 3.14

同様に、次の 3 つのコード行もまた同等であると想定できます。

Application.Contents.Item(1) = 3.14159
Application.Contents(1) = 3.14159
Application(1) = 3.14159

ただし、これは Contents コレクションに含まれる最初の要素がキーを使用して定義されている場合だけです。ASP に添付されたマニュアルには記載されていませんが、前述の最初の 2 つのコード行のいずれかを使用するには、キーを使用してその要素をあらかじめ定義しておく必要があります。たとえば、Contents コレクションに 2 番目の要素を追加するとします。次のいずれかのコード行を使用して、この要素を初期化することはできません。

Application.Contents.Item(2) = 3.14159     ' WRONG.
Application.Contents(2) = 3.14159          ' WRONG.

残念ながら、この例外にも例外があります。次のコードを使用すると、2 番目の変数を初期化できます。

Application(2) = 3.14159

これらの矛盾を考えた場合、Contents コレクションに含まれる特定の要素の値を参照する際に常に一番安全な方法は、インデックスではなくキーを使用することであることがすぐにわかります。

また、メンバーのインデックスは変更される可能性があるため、Contents コレクションの特定のメンバーを参照するときもキーを使用することが重要です。たとえば、アプリケーションに次のコードがあるとします。

Application("strFirstName") = "Arthur"
Application("strMiddleName") = "Keyton"
Application("strLastName") = "Weissinger"

これらの変数が Contents コレクションに追加された最初の 3 つの変数であるとすると、後でそのインデックスを使用してそれぞれを参照できます。

strFirst = Application(1) 
strMiddle = Application(2)
strLast = Application(3)

ただし、コレクションから変数を完全に削除する Remove メソッド (本章の後の部分を参照) を使用して strMiddleName 変数を削除する場合、インデックス番号が変更されます。

Session.Contents.Remove("strMiddleName")

strFirst = Application(1)          ' Initializes to "Arthur" 
strMiddle = Application(2)         ' Initializes to "Weissinger"
strLast = Application(3)           ' Initializes to Undefined.
Key

Contents コレクションの特定の要素の名前を表します。各要素の値は Item プロパティで表されるということを思い出してください。同様に、各要素の名前は、Key プロパティによって表されます。

特定のキーの名前が不明な場合は、順序参照を使用して取得できます。たとえば、コレクションに含まれる 3 番目の要素のキー名を取得してから、その要素の値を取得するとします。この場合は、次のコードを使用できます。

strKeyName = Application.Contents.Key(3)
strKeyValue = Application.Contents.Item(strKeyName)
Count

Contents コレクションに含まれる要素の合計数を表します。

 
メモ

アプリケーションレベルの変数を初期化できるので、2 つの方法のいずれかにより、Contents コレクションに要素を追加できます。まず、例 4.1 で示すように、"GLOBAL.ASA" ファイル内の Application_OnStart イベントプロシージャに含まれる Application 変数を初期化できます。

"GLOBAL.ASA" に含まれるアプリケーションレベルの変数の初期化

' < FROM GLOBAL.ASA >
' This code resides in the GLOBAL.ASA file at the
' root of the current application.
' See Chapter 11 for more details on the GLOBAL.ASA file.

Sub Application_OnStart

   Application.Contents.Item("STATE_FIRST") = "California"
   Application.Contents("STATE_SECOND") = "Oregon"
   Application("STATE_THIRD") = "Washington"

End Sub

例 4.1 のコードは、3 つのアプリケーションスコープの変数を作成し、Contents コレクションに 3 つの要素を追加します。これらの変数がインスタンス化されて初期化されるのは、後続のユーザーがサイトを閲覧するたびにではなく、アプリケーションの開始時だけです。これらの変数は、すべてのページとすべてのユーザーについて別のスクリプトによって変更されない限り同じ値を保持します。

前述のコードは、キーを使用して Contents コレクションに要素を追加します。また、以下のように、インデックス値を使用してコレクションに要素を追加することもできます。

Application.Contents(1) = "California"

ただし、コレクションに要素を追加するときは、キーまたはインデックスのいずれかを使用します。両方使用することはできません。インデックスとキーの両方で要素を追加した場合、キーを使用した要素により、キーが割り当てられていない下位の要素が上書きされます。

また、アプリケーションスコープの変数を初期化できるため、任意のページのスクリプト内の Contents コレクションに要素を追加できます。ただし、この方法で作成した変数は、アプリケーション全体とユーザーすべてに対して作成されて保持されます。例 4.2 に、アプリケーションスコープの変数を初期化するメソッドを示します。

サーバー側のスクリプトに含まれるアプリケーションレベルの変数の初期化

<%
' This code exists in the server-side section of a script
' on the web site.
Application.Contents.Item("STATE_FOURTH") = "New York"
Application.Contents("STATE_FIFTH") = "New Jersey"
Application("STATE_SIXTH") = "Vermont"

%>

例 4.2 に示すコードは、さらに 3 つのアプリケーションスコープ変数をアプリケーションに追加します。これらの変数は、ユーザーがこのコードを含むページを要求するたびに再初期化されます。こうしたプロセッサ能力の浪費を防ぐには、次のようなコードを使用してこの初期化を実行することをお勧めします。

<%
' A more efficient example of the creation of an 
' application-scoped variable.
If IsEmpty(Application.Contents.Item(STATE_SEVENTH)) Then
   Application.Contents(STATE_SEVENTH) = "Texas"
End If

%>

このコードは、現在のアプリケーションの 7 番目のアプリケーション変数を、既に作成されていない場合にのみ作成します。

Contents コレクションは、コレクションを繰り返し使用するために、For Each および For...Next 構成要素をサポートしています。その例を例 4.3 に示します。

Contents コレクションでの For Each の使用

<%
For Each strKey in Application.Contents
%>
   The next item in Application's Contents collection<BR>
   has <%= strKey %> as its key and
   <%= Application.Contents(strKey) %>
   as its value.<P>
<%
Next %>

ただし、多くのコレクションオブジェクトとは異なり、Contents コレクションでは Add メソッドはサポートされず、IIS 5.0 までは Remove メソッドもサポートされていませんでした。アプリケーションスコープで特定された変数は、明示的に削除しない限り、Web サーバーが停止するか、最後のユーザーセッションがタイムアウトするまで常駐します。

Application の Contents コレクションにオブジェクトを追加する場合は、オブジェクトのスレッドモデルがアプリケーションスコープでの使用をサポートしていることを確認してください。フリースレッドモデルの使用をお勧めします。IIS サーバーコンポーネントでの各種スレッドモデルの使用に関する詳細については、O'Reilly 社発行の Shelley Powers 著『Developing ASP Components』を参照してください。&

フリースレッドモデルのアプリケーションを使用すると、複数のユーザープロセスがコンポーネントの同じインスタンスに同時にアクセスできます。

アプリケーションスコープのオブジェクトのプロパティまたはメソッドにアクセスするには、構文の拡張機能を使用します。この機能については、既にアプリケーションスコープの変数値へのアクセスの項で説明しています。そのコード例を次に示します。

' In this example, assume you have an application-scoped Ad 
' Rotator variable called MyAdRot.

' Accessing a property:
intBorder = Application.Contents("MyAdRot").Border

' Executing a method:
Application.Contents("MyAdRot").GetAdvertisement("Sched.txt")

ObjectContext オブジェクトを使用しているトランザクションで特定のオブジェクトを使用する場合、そのオブジェクトにアプリケーションまたはセッションのスコープを指定しないでください。トランザクションで使用したオブジェクトは、トランザクション終了時に削除されるので、その後のオブジェクトのプロパティ参照やメソッド呼び出しでエラーが生じます。

Application オブジェクトの Contents コレクションに配列を追加する場合は、配列全体をまとめて追加します。配列の要素を変更する場合、配列のコピーを取得し、要素を変更してから、Contents コレクションに配列全体を再度追加します。例 4.4 のコードでこの例を示します。

Contents コレクションに含まれる配列の処理

<%
' Create an array variable and add it to Contents collection.
ReDim arystrNames(3)

arystrNames(0) = "Chris"
arystrNames(1) = "Julie"
arystrNames(2) = "Vlad"
arystrNames(3) = "Kelly"

Application("arystrUserNames") = arystrNames

%>

The second name in the User Names array is 
<%= Application("arystrUserNames")(1) %>
<BR>
<%

' Change an element of the array being held in the
' Contents collection.
Dim arystrNamesLocal

arystrNamesLocal = Application("arystrUserNames")
arystrNamesLocal(1) = "Mark"

Application("arystrUserNames") = arystrNamesLocal
' The second name is now Mark.

%>
Now, the second name in the User Names array is
<%= Application("arystrUserNames")(1) %>
<BR>
 
Remove  
Application.Contents.Remove(Key|Index)
 

Contents コレクションから特定のメンバーを削除します。IIS 5.0 に追加された Remove メソッドを使用すると、メモリから Application の Contents コレクションの特定の変数を削除できます。この場合、他のすべての変数が削除されることはありません。

 
パラメータ
Key

削除する Contents コレクションの特定メンバーの名前を指定する文字列変数です。

Index

削除する Contents コレクションのメンバーのインデックスを指定する整数変数です。

 

次のスクリプトは Contents コレクションの 2 つのメンバーを削除します。

<%
' This script assumes you have set up two greeting salutations for all
' the members of your site based on time of day. You want to now 
' remove these from your site.
strAppMorningGreeting = Application("strAMGreet")
strAppEveningGreeting = Application("strPMGreet")

.
.
.
Application.Contents.Remove("strAMGreet")
Application.Contents.Remove("strPMGreet")
.
.
.
%>
 
メモ

Remove メソッドは Contents コレクションへの重要な追加機能であり、より効果的なメモリ管理とクリーンアップを可能にします。 これにより、ユーザーセッションを中断しないで、コレクションの要素の一部をメモリから削除できます。Contents コレクションの Item プロパティで既に説明したとおり、Remove メソッドを呼び出すときは、インデックスではなく文字列キーを使用することが非常に重要です。要素のインデックスはアプリケーションの継続期間中に変化する可能性があり、インデックスの値を使用した Remove メソッドの呼び出しは、予期せぬ結果につながることがあります。

Application の Contents コレクションの Remove メソッドでは、IIS Web 管理インターフェイスを使用して Web アプリケーション全体をアンロードしなくても、Contents コレクションのメンバーを削除できます。以前の IIS 5.0 ではこの機能が十分でなかったため、アプリケーションスコープの変数の管理が困難でした。

 
RemoveAll  
Application.Contents.RemoveAll
 

Contents コレクションからすべてのメンバーを削除します。IIS 5.0 に追加された RemoveAll メソッドにより、アプリケーション自体をアンロードしなくても、すべてのアプリケーションスコープの変数をメモリから削除できます。

 
パラメータ

なし

 

次のスクリプトは Contents コレクションのすべてのメンバーを削除します。

<%
' This script assumes you have set up two greeting salutations for all 
' the members of your site based on time of day. You want to now remove 
' these from your site.
strAppMorningGreeting = Application("strAMGreet")
strAppEveningGreeting = Application("strPMGreet")

.
.
.
Application.Contents.RemoveAll
.
.
.
%>
 
メモ

Remove メソッドと同様、RemoveAll メソッドは Contents コレクションへの重要な追加機能であり、より効果的なメモリ管理とクリーンアップを可能にします。このメソッドにより、アプリケーション自体をアンロードしなくても、すべてのアプリケーションスコープの変数をメモリから削除できます。

 
StaticObjects  
<OBJECT RUNAT=Server SCOPE=Application ID=AppInfo2 
        PROGID="MSWC.MyInfo">
</OBJECT>
 

StaticObjects コレクションには、 <OBJECT> タグを使用してアプリケーションに追加したすべてのオブジェクトが含まれます。StaticObjects コレクションの Item プロパティ (詳細については後述) を使用すると、コレクションに含まれる特定のオブジェクトのプロパティを取得できます。また、StaticObjects コレクションの Item プロパティを使用して、コレクションに含まれる指定オブジェクトの特定のメソッドにアクセスすることもできます。

このコレクションにオブジェクトを追加するには、"GLOBAL.ASA "ファイルの "<OBJECT>" タグを使用する必要があります。その例を次に示します。

<OBJECT RUNAT=Server SCOPE=Application ID=AppInfo2 
        PROGID="MSWC.MyInfo">
</OBJECT>

ASP アプリケーションの他の場所では、このコレクションにオブジェクトを追加できません。

StaticObjects コレクションには、他の ASP コレクションと同様、次のプロパティが含まれています。

Item

コレクションに含まれる特定の要素への参照を返します。アイテムを指定するには、インデックス番号またはキーを使用します。

Key

コレクションに含まれる特定の要素の名前を返します。名前は <OBJECT> タグの ID 属性で指定します。たとえば、次のようなコレクションに含まれる最初の要素の名前を受け取る可能性があります。

objElement = Application.StaticObjects.Key(1)

Key プロパティの値を使用して、要素の値を名前で取得します。たとえば、StaticObjects コレクションに含まれる最初のオブジェクトの名前が MyAdRotator であるとします。その場合、次のコード行を使用して、そのオブジェクトの Border プロパティの値を設定または取得できます。

strKey = Application.StaticObjects.Key(1)
Application.StaticObjects.Item(strKey).Border = 0
Count

コレクションに含まれる現在の要素の数です。

コレクションの Item プロパティ、Key プロパティ、および Count プロパティの詳細については、本章で前述の「Contents コレクション」を参照してください。

' < FROM GLOBAL.ASA >
' This code resides in the GLOBAL.ASA file at the root
' of the current application. The following <OBJECT>
' tag is processed only once for the current application.
' See Chapter 11 for more details on the GLOBAL.ASA file.

<OBJECT RUNAT=Server 
SCOPE=Application
ID=AppInfo1 
PROGID="MSWC.MyInfo">
</OBJECT>

' <>

<%
' The following code initializes the AppInfo1 component.
' This initialization code can reside anywhere.
AppInfo1.PersonalName = "Gertrude Stein"
AppInfo1.PersonalAddress = "233 Main Street"

' The following code uses the StaticObjects collection 
' of the Application object to retrieve the value
' of the PersonalName property of AppInfo1. 
For Each objInfo In Application.StaticObjects
%>
   The personal name is <BR>
   <%= Application.StaticObjects(objInfo).PersonalName%><P>
<%
Next
%>

There are <%= Application.StaticObjects.Count %> items
in the Application's StaticObjects collection.
 
メモ

StaticObjects コレクションでは、<OBJECT> タグの使用によりアプリケーションレベルのスコープでインスタンス化したオブジェクトにアクセスできます。オブジェクトはサーバーを使用してインスタンス化されています。CreateObject メソッドには、このコレクションを介してアクセスすることはできません。ここでの命名法はやや複雑です。繰り返しループを実行するために、StaticObjects コレクションには、Server オブジェクトの CreateObject メソッドではなく、<OBJECT> タグを使用してインスタンス化したサーバー オブジェクトが含まれています。

Microsoft による IIS 4.0 マニュアルに記載されている StaticObjects の例では、このコレクションに対してループを実行すれば、各プロパティを参照できるとされています。これは誤解を招く可能性があります。それは、マニュアルではコレクションはオブジェクトそのものを表すのではなく、実際はオブジェクトのすべてのプロパティを表すとなっているからです。StaticObjects コレクションに含まれるオブジェクトのプロパティまたはメソッドにアクセスする場合、前の例で示したように、Key の両側のかっこの外側にドット演算子を使用し、その後にプロパティまたはメソッドの名前を記述する必要があります。

"GLOBAL.ASA" ファイルに作成したオブジェクトは、そのオブジェクトのプロパティまたはメソッドを最初に呼び出すまで、サーバー上では実際にインスタンス化されません。したがって、StaticObjects コレクションを使用してこれらのオブジェクトのプロパティまたはメソッドにアクセスできるのは、アプリケーションに含まれる他の一部のコードによりサーバー上でオブジェクトがインスタンス化された後になります。

ObjectContext オブジェクトを使用して、トランザクションで使用するオブジェクトにアプリケーションまたはセッションスコープを追加しないでください。トランザクションで使用したオブジェクトはトランザクション終了時に削除されるため、その後のオブジェクトのプロパティ参照やメソッド呼び出しでエラーが生じます。

 
Lock  
Application.Lock
 

Lock メソッドは Application オブジェクトをロックし、他のクライアントが Contents コレクションに含まれる任意の変数の値 (Unlock メソッドの呼び出し前に変更する変数だけでなく) を変更しないようにします。対応する Unlock メソッドを使用して Application オブジェクトを解除できるので、他のクライアントは Contents コレクションの変数の値を再び変更できます。Unlock メソッドを使用できない場合、IIS では、現在の ASP スクリプトの終了時、またはスクリプトのタイムアウト時のいずれか最初の時点で、変数のロックを自動的に解除します。

ASP スクリプトのタイムアウトは、Microsoft 管理コンソール (Microsoft Management Console) を使用している Web サイトの Properties ページで調整できます。初期設定値は 120 秒です。

 
パラメータ

なし

 
<%
' This script exists on the second page of a 
' multipage ASP application, so that users may
' or may not visit it. The example shows how you could
' see how many visitors the page has had.
' Assume that TotalNumPage2 starts at 0.

' Lock the Application object.
Application.Lock

intNumVisits = Application.Contents("TotalNumPage2")
intNumVisits = intNumVisits + 1
Application.Contents("TotalNumPage2") = intNumVisits

' Explicitly unlock the Application object.
Application.Unlock

' NOTE: Using the PageCnt.DLL would be a more
' efficient manner of doing this.

%>
<HTML>
<HEAD><TITLE>Home Page</TITLE></HEAD>
<BODY BGCOLOR = #ffffcc>
Welcome to our homepage. You are client number 
<%= Application.Contents("TotalNumPage2")%> to our site. Thank you for your patronage.
</BODY>
</HTML>
 
メモ

Web サーバーに接続しているクライアントは、Application Contents コレクションに含まれる変数の値を変更するスクリプトを呼び出す可能性があります。したがって、Contents コレクションに含まれる変数を参照または変更するときは、常に Lock メソッドと Unlock メソッドを使用することをお勧めします。これにより、あるクライアントが変数の値を解決しているときに、別のクライアントがその変数の値を変更することを回避できます。

IIS では Application オブジェクトのロックが自動的に解除されます。このため、対応する Unlock の呼び出しなしでは、Lock メソッドへの呼び出しを使用して読み取り専用の変数を作成できないことに注意してください。

Application_OnStart イベントプロシージャの Lock メソッドおよび Unlock メソッドを呼び出す必要はありません。Application_OnStart イベントの詳細については、本章の「イベントリファレンス」を参照してください。Application_OnStart イベントは、最終的に初期化されるセッションの数に無関係に、1 回だけ発生します。最初のクライアントの要求のみが Application_OnStart イベントを発生させます。したがって、そのクライアントのみが特定の Application 変数の値を変更できます。また、Application_OnStart コードが完了するまで、他のクライアントの要求は処理されません。

 
Unlock  
Application.Unlock
 

Unlock メソッドは、Lock メソッドの呼び出しによりアプリケーション変数のロックを解除します。Unlock メソッドを呼び出すと、他のクライアントは Application Contents コレクションに含まれている変数の値を再度変更できるようになります。Lock メソッドを呼び出し、対応する Unlock メソッドを指定しない場合、IIS では、現在の ASP の最後、または、スクリプトのタイムアウト時のいずれか最初の時点で、Application Contents コレクションに含まれている変数を自動的に解除します。

 
パラメータ

なし

 

Application.Lock の例を参照してください。

 
メモ

Application.Lock のメモを参照してください。

 
OnEnd  
Application_OnEnd
 

Application_ OnEnd イベントは、Microsoft 管理コンソールを使用して ASP アプリケーション自体を Web サーバーからアンロードしたとき、またはアプリケーションを何らかの理由 (Web サーバー上の Web サービスを停止するなど) で間違って停止したときに発生します。Application_OnEnd イベントは、1 つのアプリケーションに対して 1 回のみ呼び出されます。このイベントプロシージャのコードは "GLOBAL.ASA" ファイルに保存され、ファイルに含まれている他のすべてのコードの後に処理されます。これは、任意のアプリケーションスコープの変数の後に削除する、Application_OnEnd イベントのコード内にあります。

 
パラメータ

なし

 
' < FROM GLOBAL.ASA >
' This code resides in the GLOBAL.ASA file at the
' root of the current application. The following
' procedure is processed only once for the current
' application.
' See Chapter 11 for more details on the GLOBAL.ASA file.

<SCRIPT LANGUAGE="VBScript" RUNAT=Server> 
Sub Application_OnEnd

' This code will run on the server when
' the application stops.
' This code saves the final count of an application
' use counter to a file.
Set filsysObj1 = _
    CreateObject("Scripting.FileSystemObject")
Set tsObj1 = filsysObj1.CreateTextFile("c:\usrcount.txt", _
             True)
tsObj1.WriteLine(Application.Contents("AppUserCount"))
tsObj1.Close

End Sub 
</SCRIPT> 

' <>
 
メモ

Application_OnEnd イベントの使用には注意が必要です。Microsoft のマニュアルでは、アクティブなセッションがなくなった場合に OnEnd イベントが発生するとしています。ただし、これはその例には該当しません。Web サービスが中断したとき、または、管理者が Web サーバーのメモリから MMC を使用してアプリケーションを明示的にアンロードしたときにのみ、OnEnd が実行されます。何の不具合も発生せずに、またはユーザーの直接介入なしで、アプリケーションからこのイベントが呼び出されると想定することはできません。これは、何らかのアプリケーションレベルの変数を使用する前に、その意味を慎重に検討することのもう 1 つの理由となります。

Server オブジェクトメソッド "MapPath" を使用して、Application_OnEnd イベントプロシージャ内で、相対ディレクトリまたは仮想ディレクトリを物理ディレクトリにマップすることはできません。Server オブジェクトの詳細については、第 9 章を参照してください。Microsoft はこの制限についての理由を記載していませんが、セキュリティに関する制御のためと思われます。

 
OnStart  
Application_OnStart
 

Application_OnStart イベントは、最初のクライアントの要求を受け取ると発生します。Application_OnStart イベントは、1 つのアプリケーションに対して 1 回のみ呼び出されます。このイベントプロシージャのコードは "GLOBAL.ASA " ファイルに保存され、ファイルに含まれている他のコードやオブジェクトのインスタンス化の前に処理されます。

 
パラメータ

なし

 
' < FROM GLOBAL.ASA >
' This code resides in the GLOBAL.ASA file at the
' root of the current application. The following
' procedure is processed only once for the current
' application.
' See Chapter 11 for more details on the GLOBAL.ASA file.

<SCRIPT LANGUAGE="VBScript" RUNAT=Server> 
Sub Application_OnStart

' This code will run on the server when
' the application starts.
' This code retrieves the last final user count
' and uses it to initialize an Application
' variable.
Set filsysObj1 = CreateObject("Scripting.FileSystemObject")
Set tsObj1 = filsysObj1.OpenTextFile("c:\usrcount.txt", _
             True)
Application.Contents("AppUserCount") = tsObj1.ReadAll
tsObj1.Close

End Sub 
</SCRIPT> 

' <>
 
メモ

Application_OnStart イベントプロシージャが存在する場合、それは、指定された ASP アプリケーションのサーバー上で実行される最初のコードとなります。したがって、アプリケーションレベルの変数を初期化するには最適な場所となります。ASP アプリケーションに含まれている他のコードは、確実に実行されるとは限りません。

アプリケーションレベルの変数の使用については、慎重に検討する必要があります。Application_OnStart イベント内でサイズを変更し、初期化したアプリケーションレベルのスコープを使用するすべての変数は、アプリケーションの終了時までサーバー上のメモリを占有し続けます。