はじめに
動的なコンテンツを使用するWebアプリケーションを扱ったことがある人なら誰でも、データアクセスが大きなボトルネックになり得ることをご存じでしょう。ASP.NETランタイムの優れた機能の1つに、System.Web.Caching
名前空間を介したデータキャッシングサービスがあります。多くの開発者が直面する課題は、事前にデータキャッシングの計画をどのように立て、コードがあまり複雑にならないような形でそれをどのように効果的に実装するかということです。本稿では、ASP.NETのデータキャッシングの機能の概要を紹介します。また、データキャッシングを行う非常に簡単なプラグインアセンブリを100行に満たないコードで作成する方法についても説明します。ASP.NETページでこのアセンブリを使用すると、大量のコードを追加しなくてもWebアプリケーションのパフォーマンスを簡単に改善することができます。
ASP.NETのデータキャッシングの基本
ASP.NETのデータキャッシングでは、メモリ内にアプリケーション全体をスコープとするスレッドセーフな「バケツ」が用意され、そこに任意のシリアル化可能なオブジェクトやオブジェクトコレクションを格納することができます。この機能を利用して、負荷の高いデータベースクエリの結果や巨大なXMLドキュメント、さらには単純な配列や独自に設計したカスタムオブジェクトまで格納することができます。そうすれば、Webアプリケーションが稼働している間は、基のソースを毎回参照しなくても、このデータをキャッシュから呼び戻すことができます。しかも、データキャッシュには、キャッシュ内のアイテムの有効期間を設定できる機能があります。これを利用して、場合によっては、基になるデータが変更されたときにキャッシュを自動的に更新することができます。
そこで課題となるのは、この高性能のオブジェクトを、Webアプリケーション開発で使いやすいツールに変えることです。この記事では、この目的を実現するために、ASP.NETのデータキャッシングで最もよく使われる機能をカプセル化した1つのユーティリティクラスと、キャッシュのデータを挿入、更新、および再取得するためのショートカットを提供するヘルパークラスを作成します。
キャッシュユーティリティクラスの設計
キャッシュされたアイテムを簡単に操作できるように、主要な機能をカプセル化した単純なクラスを用意することにします。このユーティリティクラスを使うことで、キャッシュ内のアイテムの読み出し、書き込み、列挙、および削除を簡略化します。次に示すのは、ユーティリティクラスに含まれるメソッドの一覧と、各メソッドに対応する引数です。
public static string ListCache() public static string ListCache(string mask) public static void ClearCache() public static void ClearCache(string mask) public static object GetCacheItem(string key) public static void DropCacheItem(string key) public static void SetCacheItem(string key, object data) public static void SetCacheItem(string key, object data, CacheDependency dependencies) public static void SetCacheItem(string key, object data, int seconds) public static void SetCacheItem(string key, object data, int seconds, int slidingSeconds)
GetCacheItem
とDropCacheItem
はとても単純で、指定したアイテムを返すか削除する働きをします。ListCache
は、キャッシュ内のアイテムのリストを返します。このメソッドには2つのバージョンがあり、一方のバージョンでは、返されるアイテムを制御するためにフィルタ文字列を指定することができます。ClearCache
は、キャッシュ内のすべてのアイテム、またはフィルタ文字列に一致するアイテムを削除します。
SetCacheItem
は、面白い働きをするメソッドです。このメソッドを使うと、キャッシュにアイテムを追加し、必要に応じて依存関係(通常はファイル名)や有効期間の値(オブジェクトの秒単位の最大有効期間および最大アイドル時間)を設定することができます。依存関係の設定では、キャッシュされたアイテムをディスクファイルなどの外部のアイテムに関連付けます。そのディスクファイルが変更されると、アイテムがキャッシュから自動的に削除されるというしくみです。ASP.NETでは、このような方法で「Web.config」ファイルの変更を追跡しています。
有効期間のポリシーはもう少し複雑です。オブジェクトに有効期間(このクラスでは秒単位)を設定することができます。キャッシュ内のオブジェクトが有効期間を過ぎると、そのオブジェクトは自動的に削除されます。また、オブジェクトにアイドル時間(このクラスでは秒単位)を設定することもできます。オブジェクトがアイドル状態のまま、つまりどこからも要求されずに、指定した秒数が過ぎると、そのオブジェクトはキャッシュから削除されます。次に示すのは、有効期間とアイドル時間を処理するSetCacheItem
メソッドのコードです。
public static void SetCacheItem(string key, object data, int seconds, int slidingSeconds) { if(slidingSeconds>0) HttpContext.Current.Cache.Insert(key,data,null, System.DateTime.MaxValue,TimeSpan .FromSeconds(slidingSeconds)); else HttpContext.Current.Cache.Insert(key,data,null, System.DateTime.Now.AddSeconds(seconds), TimeSpan.FromSeconds(slidingSeconds)); }
ListCache
メソッドは、キャッシュ内のすべてのアイテムの簡単なリストを(HTML形式で)返します。キャッシュ内のアイテムのリストを返す際の唯一の注意点は、キャッシュコレクションを「見て回る」ために列挙子を使う必要があることです。
public static string ListCache(string filter) { StringBuilder sb = new StringBuilder(); string key=""; System.Collections.IDictionaryEnumerator en = HttpContext.Current.Cache.GetEnumerator(); while(en.MoveNext()) { key=en.Key.ToString(); if(filter.Length!=0 && key.IndexOf(filter)!=-1) sb.AppendFormat("{0}",key); if(filter.Length==0) sb.AppendFormat("{0}",key); } return sb.ToString(); }
ここまでは、ASP.NETのCache
クラスへのアクセスを容易にするユーティリティクラスの概要を紹介しました。次は、このクラスのメソッドを使用して、キャッシュコレクションへの高レベルのアクセスを実現するヘルパークラスを作成します。