Partager via


Comment : avertir une application lorsqu'un élément est supprimé du cache

Mise à jour : novembre 2007

Dans la plupart des scénarios de cache, lorsqu'un élément est supprimé du cache, vous n'êtes pas obligé de l'y replacer tant qu'il n'est pas à nouveau requis. Le schéma classique de développement est de toujours vérifier la présence de l'élément dans le cache avant de l'utiliser. Si l'élément se trouve dans le cache, vous pouvez l'utilisez. S'il ne s'y trouve pas, récupérez-le et rajoutez-le au cache.

Dans certaines circonstances, il peut cependant s'avérer utile d'avertir votre application qu'un élément est supprimé du cache. Vous pouvez, par exemple, avoir en cache un rapport dont la création nécessite un temps de traitement considérable. Lorsque ce rapport est supprimé du cache, vous souhaitez qu'il soit régénéré et placé immédiatement dans le cache afin que la prochaine fois qu'il sera demandé, l'utilisateur ne soit pas obligé d'en attendre le traitement.

Pour permettre la notification de la suppression des éléments du cache, ASP.NET fournit le délégué CacheItemRemovedCallback. Le délégué définit la signature à utiliser lorsque vous écrivez un gestionnaire d'événements appelé en réponse à la suppression d'un élément du cache. ASP.NET fournit également l'énumération CacheItemRemovedReason, qui sert à spécifier la raison de la suppression de l'élément du cache.

En général, vous implémenterez le rappel en créant un gestionnaire dans un objet métier chargé de gérer les données de cache que vous essayez de récupérer. Par exemple, vous pouvez avoir un objet ReportManager ayant deux méthodes, GetReport et CacheReport. La méthode de rapport GetReport vérifie le cache pour voir si le rapport y figure déjà. Si tel n'est pas le cas, elle le régénère et le place en cache. La méthode CacheReport a la signature de fonction du délégué CacheItemRemovedCallback ; lorsque le rapport est supprimé du cache, ASP.NET appelle la méthode CacheReport, qui le rajoute alors au cache.

Pour avertir une application lorsqu'un élément est retiré du cache

  1. Créez une classe qui sera chargée de récupérer l'élément dans le cache et de gérer la méthode de rappel pour le rajouter au cache.

  2. Dans la classe, créez une méthode qui ajoute un élément au cache.

  3. Dans la classe, créez une méthode qui récupère un élément dans le cache.

  4. Créez une méthode qui gère le rappel de la suppression de l'élément du cache. La méthode doit avoir la même signature de fonction que le délégué CacheItemRemovedCallback. Dans la méthode, exécutez la logique que vous souhaitez lancer lorsque l'élément est supprimé du cache, par exemple régénérer l'élément et le rajouter au cache.

Pour tester le rappel de l'élément du cache

  1. Créez une page Web ASP.NET qui appelle la méthode qui, dans votre classe, ajoute l'élément au cache.

    L'exemple de code suivant montre comment appeler la méthode GetReport de la classe ReportManager (définie dans l'exemple qui suit la procédure). Il affiche ensuite le rapport dans un contrôle Label nommé Label1 pendant la méthode Page_Load de la page.

    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. Demandez la page ASP.NET dans un navigateur et consultez le rapport.

    Le rapport est créé la première fois que la page est demandée et les demandes suivantes y accéderont depuis le cache jusqu'à ce qu'il soit supprimé.

Exemple

L'exemple de code suivant montre une classe complète nommée ReportManager, qui gère la notification avertissant qu'un élément est supprimé du cache. La classe gère un rapport sous la forme d'une chaîne qui représente un processus de longue durée.

Bien que l'exemple utilise une classe déclarée comme static (Shared en Visual Basic), il n'est pas nécessaire d'utiliser une classe statique. Toutefois, la méthode qui gérera le rappel doit déjà exister au moment où l'élément en cache est supprimé. Par exemple, vous ne devez pas implémenter le gestionnaire de rappel dans une page ASP.NET, celle-ci pouvant être supprimée avant que l'élément ne soit lui-même supprimé du cache, ce qui rendrait indisponible la méthode chargée de gérer le rappel. L'utilisation d'une classe statique pour la méthode qui gère le rappel garantit que la méthode existera encore lorsque l'élément sera supprimé du cache. Toutefois, l'inconvénient d'une classe statique est que toutes les méthodes statiques doivent être thread-safe.

Attention :

N'affectez pas à CacheItemRemovedCallback une méthode située dans une page. Non seulement une méthode page risque de ne pas être disponible pour un rappel une fois la page supprimée, mais le fait d'adresser le rappel à une méthode page peut empêcher le garbage collection de libérer la mémoire utilisée par la page. La raison en est que le rappel contient une référence à la page et que le garbage collector ne supprimera de la mémoire aucun élément comportant des références. La mémoire risquera alors de s'épuiser très rapidement pendant les périodes de charge d'application.

L'exemple de classe inclut les fonctionnalités suivantes :

  • Un membre privé pour savoir si le rapport a été supprimé du cache.

  • Une méthode nommée CacheReport, qui ajoute un élément au cache sous le nom MyReport et qui règle l'expiration de l'élément sur une minute après son ajout au cache. La méthode passe également la méthode ReportRemovedCallback au paramètre onRemoveCallback, qui enregistre la méthode ReportRemoveCallback afin qu'elle soit appelée lorsque l'élément est supprimé du cache.

  • Une méthode nommée GetReport, qui récupère un élément dans le cache. La méthode détermine si l'élément nommé MyReport existe dans le cache. Si l'élément n'existe pas, la méthode appelle CacheReport,, qui ajoute l'élément au cache.

  • Une méthode nommée ReportRemovedCallback, qui gère le rappel de suppression de l'élément du cache. ReportRemovedCallback a la même signature de fonction que le délégué CacheItemRemovedCallback. La méthode donne à la variable _reportRemovedFromCache la valeur true, puis rajoute l'élément au cache via la méthode 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

Voir aussi

Tâches

Comment : ajouter des éléments au cache

Comment : récupérer des valeurs d'éléments mis en cache

Comment : supprimer des éléments du cache dans ASP.NET

Concepts

Vue d'ensemble de la mise en cache ASP.NET

Configuration du cache dans ASP.NET

Mise en cache de données d'application