方法 : キャッシュから項目が削除されたときにアプリケーションに通知する

更新 : 2007 年 11 月

ほとんどの場合、キャッシュから削除された項目は、再び必要になるまでキャッシュに戻す必要はありません。一般的な開発では、使用する前に項目がキャッシュにあるかどうかを常にチェックするようにします。キャッシュに項目がある場合はそれを使用します。キャッシュに項目がない場合は、再び取得してキャッシュに戻します。

ただし、キャッシュから項目が削除される際にアプリケーションが通知を受け取ることが便利な場合があります。たとえば、作成にかなりの処理時間を要するキャッシュされたレポートがあるとします。このレポートがキャッシュから削除されたときに、それを再作成してすぐにキャッシュに格納するようにすると、ユーザーがこのレポートを次に要求したときに処理されるまで待つ必要がなくなります。

キャッシュから削除された項目の通知を有効にするために、ASP.NET は CacheItemRemovedCallback デリゲートを提供します。このデリゲートは、キャッシュから削除される項目に応答して呼び出されるイベント ハンドラを記述する際に使用するシグネチャを定義します。ASP.NET は、キャッシュ項目の削除の理由を指定するために使用する CacheItemRemovedReason 列挙体も提供します。

通常、取得する特定のキャッシュ データを管理するビジネス オブジェクトにハンドラを作成することによって、コールバックを実装します。たとえば、GetReport と CacheReport という 2 つのメソッドを含む ReportManager オブジェクトがあるとします。GetReport レポート メソッドは、レポートがキャッシュにあるかどうかを確認し、キャッシュにない場合は、レポートを再作成してキャッシュします。CacheReport メソッドは CacheItemRemovedCallback デリゲートと同じ関数シグネチャを持ちます。レポートがキャッシュから削除されると、ASP.NET は CacheReport メソッドを呼び出してレポートをキャッシュに戻します。

キャッシュから項目が削除されたときにアプリケーションに通知するには

  1. キャッシュから項目を取得し、コールバック メソッドを処理してキャッシュに項目を戻すためのクラスを作成します。

  2. このクラスで、キャッシュに項目を追加するメソッドを作成します。

  3. このクラスで、キャッシュから項目を取得するメソッドを作成します。

  4. キャッシュ項目の削除のコールバックを処理するメソッドを作成します。このメソッドには、CacheItemRemovedCallback デリゲートと同じ関数シグネチャを指定する必要があります。このメソッドでは、項目を再作成してキャッシュに戻すなどの、キャッシュから項目が削除されたときに実行するロジックを実行します。

キャッシュ項目のコールバックをテストするには

  1. クラスでキャッシュに項目を追加するメソッドを呼び出す ASP.NET Web ページを作成します。

    手順の下の使用例で定義されている ReportManager クラスの GetReport メソッドを呼び出すコード例を次に示します。この例は、ページの Page_Load メソッドの処理中に Label1 という名前の Label コントロールにレポートを表示します。

    protected void Page_Load(object sender, EventArgs e)
    {
        this.Label1.Text = ReportManager.GetReport();
    }
    
    Protected Sub Page_Load(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Me.Load
        Me.Label1.Text = ReportManager.GetReport()
    End Sub
    
  2. ブラウザで ASP.NET ページを要求してレポートを表示します。

    レポートはページが最初に要求されるときに作成され、その後の要求では、レポートがキャッシュから削除されるまでキャッシュにあるレポートにアクセスします。

使用例

キャッシュから項目が削除されたときの通知を処理する ReportManager という完全なクラスのコード例を次に示します。このクラスは、長時間実行されるプロセスを表す文字列の形式でレポートを管理します。

この例では static (Visual Basic では Shared) で宣言されたクラスを使用しますが、必ずしも静的クラスを使用する必要はありません。ただし、キャッシュ項目が削除されたときにコールバックを処理するメソッドが存在する必要があります。たとえば、ASP.NET ページはキャッシュから項目が削除される前に破棄されることがあり、コールバックを処理するメソッドが使用できなくなる可能性があるので、ASP.NET ページにコールバック ハンドラを実装しないでください。コールバックを処理するメソッドに静的クラスを使用すると、キャッシュから項目が削除されたときにメソッドが必ず存在します。ただし、静的クラスの短所は、すべての静的メソッドをスレッド セーフにする必要があることです。

7kxdx246.alert_caution(ja-jp,VS.90).gif注意 :

CacheItemRemovedCallback をページのメソッドに設定しないでください。コールバックがページのメソッドを指すように指定すると、ページが破棄された後にコールバックがページのメソッドを使用できなくなるだけでなく、ページが使用するメモリをガベージ コレクションがクリアできなくなります。これは、コールバックにページへの参照が含まれているために、ガベージ コレクタが参照を含む項目をメモリから削除できなくなるためです。これが原因で、アプリケーションの読み込み中にすぐにメモリ不足になることがあります。

このサンプル クラスには、次のような機能が含まれます。

  • レポートがキャッシュから削除されたかどうかを追跡するためのプライベート メンバ。

  • MyReport という名前で項目をキャッシュに追加し、キャッシュに追加されてから 1 分後に期限切れになるように項目を設定する CacheReport というメソッド。このメソッドは、ReportRemovedCallback メソッドを onRemoveCallback パラメータに渡します。このパラメータは、項目がキャッシュから削除されたときに ReportRemoveCallback メソッドが呼び出されるように登録します。

  • キャッシュから項目を取得する GetReport というメソッド。このメソッドは、MyReport という項目がキャッシュに存在するかどうかを確認します。項目がキャッシュに存在しない場合、このメソッドはキャッシュに項目を追加する CacheReport, を呼び出します。

  • キャッシュ項目の削除のコールバックを処理する ReportRemovedCallback というメソッド。ReportRemovedCallback は、CacheItemRemovedCallback デリゲートと同じ関数シグネチャを持ちます。このメソッドは、_reportRemovedFromCache 変数を true に設定し、CacheReport メソッドを使用してキャッシュに項目を戻します。

using System;
using System.Web;
using System.Web.Caching;
public static class ReportManager
{
    private static bool _reportRemovedFromCache = false;
    static ReportManager()
    { }

    public static String GetReport()
    {
        lock (typeof(ReportManager))
        {
            if (HttpContext.Current.Cache["MyReport"] != null)
                return (string)HttpRuntime.Cache["MyReport"];
            else
            {
                CacheReport();
                return (string)HttpRuntime.Cache["MyReport"];
            }
        }
    }

    public static void CacheReport()
    {
        lock (typeof(ReportManager))
        {
            HttpRuntime.Cache.Add("MyReport",
                CreateReport(), null, Cache.NoAbsoluteExpiration,
                new TimeSpan(0, 1, 0),
                System.Web.Caching.CacheItemPriority.Default,
                new CacheItemRemovedCallback(ReportRemovedCallback));
        }
    }

    private static string CreateReport()
    {
        System.Text.StringBuilder myReport = 
            new System.Text.StringBuilder();
        myReport.Append("Sales Report<br />");
        myReport.Append("2005 Q2 Figures<br />");
        myReport.Append("Sales NE Region - $2 million<br />");
        myReport.Append("Sales NW Region - $4.5 million<br />");
        myReport.Append("Report Generated: " + DateTime.Now.ToString() 
            + "<br />");
        myReport.Append("Report Removed From Cache: " + 
            _reportRemovedFromCache.ToString());
        return myReport.ToString();
    }

    public static void ReportRemovedCallback(String key, object value, 
        CacheItemRemovedReason removedReason)
    {
        _reportRemovedFromCache = true;
        CacheReport();
    }
}
Imports System
Imports System.Web
Imports System.Web.Caching
Public Class ReportManager
    Private Shared _reportRemovedFromCache As Boolean = False
    Shared Sub New()
    End Sub

    Private Sub New()
    End Sub

    Public Shared Function GetReport() As String
        SyncLock (GetType(ReportManager))
            If HttpContext.Current.Cache("MyReport") IsNot Nothing Then
                Return CStr(HttpRuntime.Cache("MyReport"))
            Else
                CacheReport()
                Return CStr(HttpRuntime.Cache("MyReport"))
            End If
        End SyncLock
    End Function

    Public Shared Sub CacheReport()
        SyncLock (GetType(ReportManager))
            HttpRuntime.Cache.Add("MyReport", CreateReport(), _
            Nothing, Cache.NoAbsoluteExpiration, New TimeSpan(0, 1, 0), _
            System.Web.Caching.CacheItemPriority.Default, _
            New CacheItemRemovedCallback(AddressOf ReportRemovedCallback))
        End SyncLock
    End Sub

    Private Shared Function CreateReport() As String
        Dim myReport As New System.Text.StringBuilder()
        myReport.Append("Sales Report<br />")
        myReport.Append("2005 Q2 Figures<br />")
        myReport.Append("Sales NE Region - $2 million<br />")
        myReport.Append("Sales NW Region - $4.5 million<br />")
        myReport.Append("Report Generated: " & _
            DateTime.Now.ToString() & "<br />")
        myReport.Append("Report Removed From Cache: " _
            & _reportRemovedFromCache.ToString())
        Return myReport.ToString()
    End Function

    Public Shared Sub ReportRemovedCallback(ByVal key As String, _
            ByVal value As Object, ByVal removedReason _
            As CacheItemRemovedReason)
        _reportRemovedFromCache = True
        CacheReport()
    End Sub
End Class

参照

処理手順

方法 : キャッシュにアイテムを追加する

方法 : キャッシュされたアイテムから値を取得する

方法 : ASP.NET のキャッシュから項目を削除する

概念

ASP.NET のキャッシュの概要

ASP.NET のキャッシュの構成

アプリケーション データのキャッシュ