Como: Notificar an aplicativo When an Item Is Removed from the cache

Na maioria das situações de cache, quando um item é removido do cache, você não precisa colocá-lo de volta no cache até que ele seja necessário novamente.O padrão típico de desenvolvimento é sempre verificar o cache para o item antes de usá-lo.Se o item está no cache, você o usa.Se não estiver, você o recupera o item novamente e, em seguida, adiciona de volta para o cache.

No entanto, em alguns casos, é útil para o seu aplicativo ser notificado quando um item é removido do cache.Por exemplo, você pode ter um relatório em cache que leva uma quantidade considerável de tempo de processamento para criar.Quando ele é removido do cache, você deseja que ele seja regenerado e colocado em cache imediatamente para que a próxima vez que for solicitado, o usuário não precise aguardá-lo ser processado.

Para habilitar a notificação de itens que estão sendo removidos do cache, o ASP.NET fornece o representante CacheItemRemovedCallback.O representante define a assinatura a ser usada quando você escreve um manipulador de eventos que é chamado em resposta a um item que está sendo removido do cache.O ASP.NET também fornece a enumeração CacheItemRemovedReason, que é usada para especificar a razão pela remoção de item de cache.

Normalmente, você implementa o retorno de chamada criando um manipulador em um objeto comercial que gerencia os dados de cache específicos que você está tentando recuperar.Por exemplo, você pode ter um objeto ReportManager que tem dois métodos, GetReport e CacheReport.O método de relatório GetReport verifica o cache para ver se o relatório já está armazenada em cache e, se não estiver, o método gera novamente o relatório e o põe em cache.O método CacheReport tem a mesma assinatura de função do representante CacheItemRemovedCallback; quando o relatório é removido do cache, o ASP.NET chama o método CacheReport, que, em seguida, o readiciona para o cache.

Para notificar um aplicativo quando um item é removido do armazenamento

  1. Crie uma classe que é responsável por recuperar o item do cache e manipular o método de retorno de chamada para adicionar o item de volta para o cache.

  2. Na classe, crie um método que adiciona um item para o cache.

  3. Na classe, crie um método que recupera um item do cache.

  4. Crie um método que controla o cache retorno de chamada de remoção de item.O método deve ter a mesma assinatura de função que o representante CacheItemRemovedCallback.No método, execute a lógica que deseja executar quando o item é removido do cache, como regenerar o item e adicioná-lo de volta para o cache.

Para testar o retorno de chamada de item de cache

  1. Crie um página da Web ASP.NET que chama o método na sua classe que adiciona o item para o cache.

    O exemplo de código a seguir mostra como chamar o método GetReport da classe ReportManager (definido no exemplo a seguir do procedimento).Em seguida, ele exibe o relatório em um controle Label chamado Label1 durante o método Page_Load da página.

    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. Solicitar a página ASP.NET em um navegador e exibir o relatório.

    O relatório é criado na primeira vez que a página é solicitada, e as solicitações subsequentes irão acessar o relatório do cache até que o relatório seja removido.

Exemplo

O exemplo de código a seguir mostra uma classe completa denominada ReportManager que trata de notificação quando um item é excluído do cache.A classe gerencia um relatório na forma de uma sequência de caracteres que representa um processo de execução longa.

Embora o exemplo usa uma classe declarada como static (Shared no Visual Basic), não é necessário que você usa uma classe estática.No entanto, o método que manipulará o retorno de chamada deve existir quando o item de cache é excluído.Por exemplo, você não deve implementar o manipulador de retorno de chamada em um página ASP.NET, porque a página pode ter sido descartada pelo tempo que item seja excluído do cache e, portanto, o método para controlar o retorno de chamada não estará disponível.O uso de uma classe estática para o método que manipula o retorno de chamada assegura que o método ainda continuará a existir quando o item for removido do cache.No entanto, uma desvantagem para a classe estática é que todos os métodos estáticos precisa ser segmento seguros.

Cuidado:

Não defina CacheItemRemovedCallback para um método em uma página.Além de um método de página não está disponível para um retorno de chamada após a página ser descartada, apontar o retorno de chamada para um método de página pode impedir que a memória usada pela página seja recuperada pela coleta de lixo.Isso acontece porque o retorno de chamada contém uma referência à página e o coletor de lixo não removerá um item de memória se o item tiver quaisquer referências.Durante períodos de carregamento de aplicativo, isso pode causar a memória ser usada muito rapidamente.

A classe exemplo inclui estes recursos:

  • Um membro particular para controlar se o relatório foi removido do cache.

  • Um método chamado CacheReport que adiciona um item para o cache sob o nome MyReport e define o item para expirar um minuto após ser adicionado ao cache.O método também passa o método ReportRemovedCallback para o parâmetro onRemoveCallback, que registra o método ReportRemoveCallback para que ele seja chamado quando o item for excluído do cache.

  • Um método chamado GetReport que obtém um item de cache.O método determina se o item chamado MyReport existe no cache.Se o item não existir, o método chama CacheReport, que adiciona o item para o cache.

  • Um método chamado ReportRemovedCallback que manipula o retorno de chamada de remoção de item do cache. ReportRemovedCallback tem a mesma assinatura de função que o CacheItemRemovedCallback delegado. O método define a variável _ reportRemovedFromCache para true e, em seguida, adiciona o item de volta para o cache via o método 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

Consulte também

Tarefas

Como: Adicionar itens ao cache

Como: Recuperar valores de itens em cache

Como: Excluir itens do cache no ASP.NET

Conceitos

Visão geral do cache no ASP.NET

Configuração de cache no ASP.NET

Cache de dados de aplicativo