Quando falamos em cache estamos falando de armazenamento de dados em memória e também de desempenho. É importante lembrar que por ser armazenado em memória os dados contidos no cache são voláteis.

Conceito

O conceito de cache é bem simples, basicamente é armazenar dados frequentemente acessados, obtidos a partir de uma origem de dados a qual normalmente não é modificada constantemente no dia, por exemplo, (Não existe uma regra para definir quando o cache deve ser implementado em uma aplicação).

Nota: O cache pode ser facilmente visto como um diferencial positivo ou negativo em uma aplicação, pois pequenas falhas na lógica de utilização podem sobrecarregar o servidor e deixar a aplicação mais lenta do que se tivesse rodando sem a implementação de uma lógica de cache.

Cache no ASP.NET

O cache fornece aos desenvolvedores a possibilidade de armazenar um dado em memória usando chave/valor.

O ASP.NET oferece possibilidades interessantes para que seja possível gerenciar este recursos com eficiência. Utilizando os recursos de gerenciamento do próprio ASP.NET é possível remover itens contidos no cache caso a sua fonte de dados seja modificada, é possível também expirar os dados do cache definindo um período máximo para sua permanência e outra possibilidade é que o ASP.NET faça a limpeza destes dados caso a memória esteja baixa.

Cache - Novas características do ASP.NET 2.0

Abaixo estão listadas características novas implementadas no ASP.NET 2.0, porém neste artigo não vou me aprofundar muito nelas e sim em uma característica existente desde a versão 1.x do ASP.NET e em artigos futuros vamos falaremos detalhadamente sobre estas mudanças.

Eu optei por falar de um recurso que posso chamar de antigo, pois notei que muitos o desconhecem apesar de ser muito útil e fácil de implementar.

Perfis de Cache

Este recurso possibilita ao usuário definir perfis no arquivo de configuração de sua aplicação web.config, onde é possível configurar todos os parâmetros do cache e esta configuração pode ser aplicada a uma ou a N página de sua aplicação, abaixo segue um exemplo da configuração de um perfil:

Listagem 1. Definição de um perfil de cache


<caching>
	<outputCacheSettings>
		<outputCacheProfiles>
			<add name="cacheteste" enabled=”true” duration="60" varyByParam=”” />
		</outputCacheProfiles>
	</outputCacheSettings>
</caching>

Customizando CacheDependency

Este recurso possibilita ao usuário criar uma classe customizada de dependência de cache, onde é preciso somente que a classe customizada herde a classe CacheDependency e implemente uma regra qualquer para expirar o cache.

SqlCacheDependency

Este recurso possibilita ao usuário definir uma dependência de cache ligada diretamente a uma tabela ou a uma linha especifica de uma tabela do SQL Server, onde ao ser modificada a linha ou a tabela o dado existente no cache é automaticamente removido.

O ASP.NET pode gerenciar modificações feitas em tabelas a partir da versão 7 do SQL Server, porém para gerenciar modificações em uma linha especifica é necessário a utilização do SQL Server 2005.

Seguimentando cache

Este recurso possibilita ao usuário definir uma área de sua página que não será armazenada no cache. Então parte será armazenada e parte não será, por exemplo, você tem uma página que exibi dados de um banco de dados, mas também exibi dados estáticos então é possível definir que a área estática não será armazenada no cache. Já que não há necessidade para tal.

Usando CacheDependency

Pesquisando e conversando com alguns amigos sobre a utilização de uma lógica de cache em nossas aplicações descobri que poucos sabiam que existe a possibilidade de associar um objeto existente no cache a uma dependência não física e os que sabiam nunca implementaram tal idéia.

Para implementar uma dependência como mencionado acima, devemos utilizar o que chamamos de keys, o ASP.NET fornece um overload na classe CacheDependency que recebe como parâmetro um array de string contendo os identificadores de objetos contidos no cache que serão as dependências a imagem 01 possibilita um entendimento melhor deste método.

Figura 1. Overload da Classe CacheDependency utilizado neste artigo

Este overload permite que sejam utilizadas chaves de itens já existentes no cache para o ASP.NET se baseie no seu conteúdo e identifique quando os objetos de cache dependentes deste devem ser removidos. A listagem 01 demonstra sua utilização.

Listagem 2. Demonstra como utilizar a dependência a partir de keys


public class Clientes
{
	public static readonly string[] ChavesMestre = new string[] {"keyCliente" };

        public List<Cliente> Listar()
	{           
		List<Cliente> nomes = new List<Cliente>();
		System.Web.Caching.Cache dadosCache = HttpRuntime.Cache;
		if (dadosCache.Get("Clientes") == null)
		{
			dadosCache.Insert(ChavesMestre[0], DateTime.Now);
			nomes.Clear();
	                nomes.Add(new Cliente(1, "Diego", "diego.dias@2dsolucoes.net"));
	                nomes.Add(new Cliente(2, "Fulano", "fulano.fulano@2dsolucoes.net"));
	                nomes.Add(new Cliente(3, "Fernando", "diego.dfsd@uol.com.br"));
	                nomes.Add(new Cliente(4, "Mario", "atendimento@2dsolucoes.com.br"));
	                System.Web.Caching.CacheDependency cd = new System.Web.Caching.CacheDependency(null, ChavesMestre);
	                dadosCache.Insert("Clientes", nomes, cd);
		}
		else
		{
			nomes.Clear();
			nomes = dadosCache.Get("Clientes") as List<Cliente>;
		}
		return nomes;
	}
}

Como podemos ver na Listagem 2 existe um método denominado de Listar que é responsável por listar clientes. Neste método podemos ver que existem algumas linhas destacadas.

Onde a linha destacada em amarelo é onde é criado um cache que pode ter um valor qualquer, mais adiante explicarei a necessidade de criá-lo.

A linha destacada em cinza é onde é criado o cache com uma lista de clientes e também onde é definida a dependência deste objeto que acaba de ser inserido no chave. Como se pode ver antes da inserção do objeto no cache é criado um objeto de dependência cujo, este objeto é o que orienta o ASP.NET quando a listagem de clientes deve ser removida do cache.

Como eu havia dito, antes de inserir a listagem de clientes no cache foi inserido no cache um objeto qualquer (neste caso a data atual) a chave que identifica este objeto será usada na criação do objeto de dependência para indicar que quando o objeto referente à chave ChavesMestre for modificado todos os demais objeto que foram associados a ele (objeto de dependência) serão removidos do cache.

Está é uma solução interessante no meu ponto de vista, até mesmo por que existem situações que não é possível gerenciar arquivos e o banco de dados não é um Sql Server.

Nota: O gerenciamento de dependência ligado direto a um banco de dados só é possível se o banco for SQL Server a partir da versão 7

Bom até os próximos artigos, onde discutiremos as demais formas de fazer dependência e vocês poderam então decidir qual é a mais adequada para sua aplicação.

Referências

  • http://msdn2.microsoft.com/en-us/library/xsbfdd8c(VS.80).aspx