.NET TIPS

[ASP.NET]アプリケーション全体で共有するデータを扱うには?(Applicationオブジェクト編)

デジタルアドバンテージ
2004/02/06

 ASP.NETには、1つのWebアプリケーション(=Webページやモジュールなどを含んでいる1つの仮想ディレクトリ)全体でグローバルなデータを保持するためにApplicationオブジェクトが用意されている。このオブジェクトは、そのWebアプリケーションに含まれているすべてのページからアクセスでき、Webアプリケーションが実行されている間(Webアプリケーション内のいずれかのページが最初にアクセスされてから、IISを再起動したりWebアプリケーションを更新したりするまでの間)は、ユーザーのセッションにかかわらず、ずっと状態が維持される。

 Applicationオブジェクトは、キーとなる文字列と値のペアでデータを格納しているコレクションである。これはPageクラス(System.Web.UI名前空間)のプロパティであるため、ページを記述している.aspxファイルや、コードビハインドによりページに関連付けられているクラスで直接参照できる。なお、Applicationオブジェクトの実体は、HttpApplicationStateクラス(System.Web名前空間)のオブジェクトである。

 例えばC#では、コード中で次のようにしてApplicationオブジェクトを読み書きできる。

Application["Title"] = "在庫管理アプリケーション";
string myTitle = (string)Application["Title"];

 VB.NETの場合には、これは次のようにして記述する。

Application("Title") = "在庫管理アプリケーション"
Dim myTitle As String = CType(Application("Title"), String)

 Applicationオブジェクトから取り出した値はObject型であるため、たいていの場合にはキャスト(型の変換)により元の型に戻してやる必要がある。

 次に、Applicationオブジェクトを利用したいくつかのVB.NETのサンプル・コードを示す。

共通の定数としてApplicationオブジェクトを使用する

 通常、データベース接続文字列やWebアプリケーションのタイトル文字列などは、Webアプリケーションの起動時に1度だけ値を設定しておき、各ページからは読み出しだけが行えればよい。このような用途でApplicationオブジェクトを利用する場合をまず見てみよう。

 Webアプリケーションの起動時にのみ1度だけ実行したいコードは、Global.asaxのApplication_Startメソッドに記述すればよい。

 Visual Studio .NETでテンプレートとして「ASP.NET Webアプリケーション」を選択して、新しいプロジェクトを作成する。この場合には、WebフォームとともにGlobal.asaxファイルが自動作成される。ソリューション・エクスプローラでこのファイルを選択してから、コードを表示させ、次の画面のように、Application_StartメソッドでApplicationオブジェクトに値を設定する。

Visual Studio .NETで編集中のGlobal.asaxファイル
コードビハインドにより、実際のコードはGlobal.asaxに関連づけられているGlobal.asax.vbに記述する。
  Global.asaxを選択して、コードを表示させる。
  Application_Startメソッドに追加したApplicationオブジェクトに値を設定するコード。

 ここでは、いま設定した文字列を画面に表示してみよう。これにはまず、ソリューション・エクスプローラでWebフォームであるWebForm1.aspxを選択し、ツールボックスよりLabelコントロールをフォーム上の適当な位置にドロップしてから、コードを表示させる。

 そして、Page_Loadメソッド内に次のようなコードを記述して実行すればよい。

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  ' ページを初期化するユーザー コードをここに挿入します。
  Label1.Text = CType(Application("Title"), String)
End Sub
Applicationオブジェクトから取り出した値を表示するコード
フォーム上に配置したLabelコントロールに値を表示する(実際に記述するコードは太字の部分のみ)。

Applicationオブジェクトを読み書きするにはロックが必要

 次に、共通の変数としてページ内でApplicationオブジェクトに値を書き込む場合を考えてみよう。この場合には少し注意が必要となる。なぜなら、複数のページから同時に同一のApplicationオブジェクトにアクセスする可能性があるため、排他処理が必要となる場合があるからだ。

 Applicationオブジェクトでは、そのコレクションの更新中に、ほかのセッション(ほかのユーザーによるアクセス)でのApplicationオブジェクトの更新を禁止するためにLockメソッドが用意されている。また、更新が終われば、UnLockメソッドを呼び出してほかのセッションが書き込めるようにしておく必要がある。

 ここでは、あるページにおいて、そのページがアクセスされた総数をカウントし、それを表示する場合について見てみる。このためのコードは例えば次のようになる。

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  ' ページを初期化するユーザー コードをここに挿入します。
  Application.Lock()
  Application("Counter") = CType(Application("Counter"), Int32) + 1
  Application.UnLock()
  Label1.Text = "カウンタ:" + Application("Counter").ToString()
End Sub
ページ・カウンタを表示するためのコード
ページがアクセスされる度にカウンタ(Application("Counter"))を+1してから、Labelコントロールに表示する。

 ページ・アクセスの総数をカウントしているApplication("Counter")には、初期値を設定しておく必要がある。これは先ほどと同様に、Application_Startメソッドで行えばよい。

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
  ' アプリケーションが開始されたときに発生します。
  Application("Counter") = 0
End Sub
ページ・カウンタを初期化するためのコード
Global.asaxファイルのApplication_Startメソッドで記述する。

 Application.Lock()を実行すると、Application.UnLock()を実行するまではApplicationオブジェクトはロックされるので、ほかのセッションではApplicationオブジェクトに書き込むことも読み出すこともできなくなる。このため、ロックしている時間はできる限り短い方がよい。

 なお、実際には単にApplicationオブジェクトに値を書き込む場合にも、Applicationオブジェクトはロックされていて、ほかのセッションは読み書きできない。さらにいえば、Applicationオブジェクトから値を読み出す場合にも、Applicationオブジェクトはロックされる。ただしこの場合には、書き込みが禁止されるだけで、ほかのセッションが読み出すことはできる。このため、Lock/UnLockメソッドが必要となるのは、Applicationオブジェクトから読み出した値を変更し、続けて書き込むような場合である。

 ところで、ASP.NET以前のWindowsのWebアプリケーション実行環境であるASPでもApplicationオブジェクトが同様に利用できたことをご存じの方も多いだろう。実はASP.NETのApplicationオブジェクトは、ASPとの互換性のために用意されているものである。これとは別に、ASP.NETではグローバルな静的変数(VB.NETでは共有変数)を利用してアプリケーション全体で共有するデータを保持することができ、こちらの方がパフォーマンスがよい。これについては「TIPS:[ASP.NET]アプリケーション全体で共有するデータを扱うには?(静的メンバ編)」で解説している。End of Article

カテゴリ:Webフォーム 処理対象:Global.asax
使用ライブラリ:Pageクラス(System.Web.UI名前空間)
使用ライブラリ:HttpApplicationStateクラス(System.Web名前空間)
関連TIPS:[ASP.NET]アプリケーション全体で共有するデータを扱うには?(静的メンバ編)
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]アプリケーション全体で共有するデータを扱うには?(静的メンバ編)
[ASP.NET]ページから生成されたソース・コードを見るには?
[ASP.NET]ポストとポストバックの違いは?
[Silverlight 2]アプリケーションのホスト情報を取得するには?
Windowsフォームで簡単に画像を表示するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間