다음을 통해 공유


방법: 캐시에서 항목이 제거될 때 응용 프로그램에 알림

업데이트: 2007년 11월

대부분의 캐시 시나리오에서는 캐시에서 항목이 제거되면 다시 필요할 때까지 해당 항목을 캐시에 다시 추가할 필요가 없습니다. 일반적으로 항목을 사용하기 전에 캐시에 해당 항목이 있는지 항상 확인하는 것이 좋습니다. 항목이 캐시에 있으면 이 항목을 사용하고 캐시에 없으면 항목을 다시 검색하여 캐시에 추가합니다.

그러나 경우에 따라 캐시에서 항목이 제거되면 응용 프로그램에 이를 알리는 것이 유용합니다. 캐시된 보고서를 만드는 데 처리 시간이 많이 소요되는 경우를 예로 들 수 있습니다. 캐시에서 항목이 제거되면 다음에 이 항목이 요청될 경우 처리될 때까지 사용자가 기다릴 필요가 없도록 항목을 다시 생성하여 바로 캐시에 추가할 수 있습니다.

캐시에서 제거되는 항목에 대한 알림을 설정하기 위해 ASP.NET에서는 CacheItemRemovedCallback 대리자를 제공합니다. 이 대리자는 캐시에서 제거되는 항목에 대한 응답으로 호출되는 이벤트 처리기를 작성할 때 사용할 시그니처를 정의합니다. 또한 ASP.NET에서는 캐시 항목이 제거되는 이유를 지정하는 데 사용되는 CacheItemRemovedReason 열거형도 제공합니다.

일반적으로는 검색할 특정 캐시 데이터를 관리하는 비즈니스 개체에서 처리기를 만들어 콜백을 구현합니다. 예를 들어 GetReport와 CacheReport라는 두 메서드가 포함된 ReportManager 개체가 있을 수 있습니다. GetReport 보고서 메서드는 캐시에 보고서가 이미 캐시되어 있는지 확인하고, 캐시되지 않은 경우에는 보고서를 다시 생성하여 캐시합니다. CacheReport 메서드는 CacheItemRemovedCallback 대리자와 함수 시그니처가 같습니다. 캐시에서 보고서가 제거되면 ASP.NET에서 CacheReport 메서드를 호출한 다음 보고서를 다시 캐시에 추가합니다.

캐시에서 항목이 제거될 때 응용 프로그램에 알리려면

  1. 캐시에서 항목을 검색하고, 이 항목을 다시 캐시에 추가할 콜백 메서드를 처리하는 클래스를 만듭니다.

  2. 항목을 캐시에 추가하는 메서드를 클래스에 만듭니다.

  3. 캐시에서 항목을 가져오는 메서드를 클래스에 만듭니다.

  4. 캐시 항목 제거 콜백을 처리하는 메서드를 만듭니다. 이 메서드는 CacheItemRemovedCallback 대리자와 함수 시그니처가 같아야 합니다. 메서드 내에서 캐시의 항목이 제거되면 실행할 논리를 수행합니다. 예를 들면 항목을 다시 생성한 후 캐시에 다시 추가할 수 있습니다.

캐시 항목 콜백을 테스트하려면

  1. 항목을 캐시에 추가하는 클래스 메서드를 호출하는 ASP.NET 웹 페이지를 만듭니다.

    다음 코드 예제에서는 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 페이지에서 콜백 처리기를 구현하면 안 됩니다. 콜백을 처리하는 메서드에 정적 클래스를 사용하면 캐시에서 항목이 제거될 때 이 메서드가 그대로 남게 됩니다. 그러나 정적 클래스를 사용하면 모든 정적 메서드가 스레드로부터 안전해야 한다는 단점이 있습니다.

주의:

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의 캐시 구성

응용 프로그램 데이터 캐싱