ASP.NET - Colocando os dados no Cache


A conexão com um banco de dados e o seu gerenciamento está entre os itens que mais consomem recursos, principalmente em aplicações Web.

Em aplicações web , que usam banco de dados , os dados usados por uma aplicação podem ser re-criados a cada ida/vinda ao servidor ou podem ser obtidos de um cache  para processamento posterior.

Quando você vai até o servidor para obter os dados novamente você tem a vantagem da certeza de sempre estar com os dados atualizados; o custo é que isto consome muito tempo e recursos , dependendo da quantidade de dados que vão trafegar na rede.

Quando você usa um cache para colocar os seus dados , você tem a vantagem de ter um acesso mais rápido pois você não precisa ir até o servidor para pegar os dados; o custo é que você pode consumir muito recursos do sistema se muitos usuários estiverem usando o cache com a mesma finalidade e os dados podem não estar sincronizados.

E Como você pode fazer o cache dos seus dados ?

Os Dados podem ser armazenados no cliente - usando o view state da página ,  ou no servidor em uma variável de estado de sessão ou aplicação, ou ainda usando o cache.

Usando o cache do lado do cliente você não consome recursos do servidor , mas requer uma largura de banda de rede maior para transmitir a informação que foi colocada no cache de volta para o servidor.

Usando o cache do lado do servidor você consome mais recursos do servidor mas requer uma largura de banda menor.

Independente de qual for a sua escolha a quantidade de dados colocados no cache deve ser minimizado para evitar problemas de desempenho e escalabilidade.

ASP.NET implementa a classe System.Web.Caching.Cache para armazenar objetos que requerem um grande quantidade de recursos do servidor para serem criados ,  forma que eles não tenham  que ser recriados a cada vez que for necessário.

Instâncias da classe cache são criadas para cada domínio da aplicação e permanecem ativos enquanto o domínio da aplicação permanecer ativo. Quando uma aplicação é re-iniciada a classe cache é re-criada.

Você pode acessar via código a informação sobre uma instância da classe cache através da propriedade cache , do objeto HttpContext ou do objeto Page.

A classe cache permite que você adote uma política de expiração para itens no cache. Itens podem ser definidos para expirar em um tempo específico; este tempo é chamado de absolute expiration. Podem também expirar se não forem acessados por período de tempo conhecido como sliding expiration. Itens que expiraram retornam um valor null.

Ao utilizar o cache para colocar os seus dados você pode aumentar o desempenho da sua aplicação pois usando o cache você evita que a aplicação tenha que ir/voltar diversas vezes ao servidor.

Um efeito colateral de usar um cache de dados sem critério é que você pode consumir muita memória do servidor/cliente e nunca esqueça que os dados podem ficar desatualizados no cache. Por isto use o cache para dados que não sofram atualização com frequência.

Depois deste parlatório vou mostrar como você pode usar o cache de dados em uma página ASP.NET que acessa um banco de dados.

Para o exemplo deste artigo eu vou usar o banco de dados Northwind.mdb e o Visual Studio.NET para criar a página Webform1.aspx.

Inicie então um novo projeto no Visual Studio .NET e selecione em Templates : ASP.NET Web Application e em Project Types : Visual Basic. O nome que informei na caixa Location para o exemplo do artigo foi : CacheDados

O VS.NET irá criar o formulário Web WebForm1.aspx , vou usar este nome mas para aplicações reais você deve usar um nome pertinente.

Usando os recursos do VS.NET insira os controles: Label(cacheStatus) ,  datagrid(dgClientes) e Button(limpaCache) no formulário conforme figura abaixo:

O code-behind (arquivo WebForm1.aspx.vb) da aplicação  contém três eventos e dois métodos:

Page.Load - Verifica o cache para um objeto com a chave CustomerCache.

Se uma entrada no cache não for encontrada o DataSet é carregado usando o método CarregaDataSet().
Se uma entrada for encontrada o DataSet o objeto no cache é retornado e é feito um cast (conversão forçada) para um DataSet.

Se a página estiver sendo carregada pela primeira vez o evento CurrentPageIndex do datagrid na página é definido para 0 (indica a primeira página) e o chamada o método VinculaGrid para exibir os dados no datagrid.

CarregaDataSet() - Carrega o DataSet da tabela Customers do banco de dados Northwind.mdb. O DataSet é incluído no cache com a chave CustomerCache e um tempo de expiração de 15 segundos é atribuido para o mesmo.

VinculaGrid() - Vincula os dados da tabela Customers no DataSet ao datagrid da página.

DataGrid.PageIndexChange - Define o índice da página atual do datagrid para um novo valor.

Vamos agora ao código do projeto:

Você vai precisar definir pelo menos um import :  

Imports System.Data.OleDb

Vai precisar definir as variáveis usadas no projeto:

Private ds As DataSet
Private conexaoSQLOleDb As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\teste\Northwind.mdb"

O evento Page_Load:

 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' carrega os dados do banco de dados ou cache e exibe a origem dos mesmos
        If Cache("CustomersDataSet") Is Nothing Then
            CarregaDataSet()
            cacheStatus.Text = "DataSet retornado do Banco de dados."
        Else
            ds = CType(Cache("CustomersDataSet"), DataSet)
            cacheStatus.Text = "DataSet retornado do cache."
        End If

        If Not Page.IsPostBack Then
            ' quando a página é aberta na primeira vez , posiciona no primeiro grid da pagina
            dgClientes.CurrentPageIndex = 0
            VinculaGrid()
        End If
    End Sub

 


O método CarregaDataSet: Aqui eu estou incluindo os dados no cache.

Private Sub CarregaDataSet() '
        ' cria o objeto DataAdapter
        Dim strSql As [String] = "SELECT * FROM Customers"
        Dim da As New OleDbDataAdapter(strSql, conexaoSQLOleDb)
        ds = New DataSet
        ' preenche a tabela customers no DataSet com todos os clientes
        da.Fill(ds, "Customers")
        ' salva o DataSet para o cache com tempo de expiração de 15 segundos
        Cache.Insert("CustomersDataSet", ds, Nothing, DateTime.Now.AddSeconds(15), System.TimeSpan.Zero)
    End Sub

 


O método VinculaGrid:

 Private Sub VinculaGrid()
        ' vincula a view padrão da tabela customers no grid
        dgClientes.DataSource = ds.Tables("Customers").DefaultView
        dgClientes.DataKeyField = "CustomerID"
        dgClientes.DataBind()
    End Sub


O evento Click do botão de comando: Aqui estou removendo os dados cache.

Private Sub limpaCache_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles limpaCache.Click
        ' remove o cache quando o usuário pressiona o botão - Limpa Cache
        Cache.Remove("CustomersDataSet")
        cacheStatus.Text = "O cache esta limpo."
    End Sub

 


O evento PageIndexChanged do DataGrid:

Private Sub dgClientes_PageIndexChanged(ByVal source As Object, ByVal e As 
System.Web.UI.WebControls.DataGridPageChangedEventArgs)  Handles dgClientes.PageIndexChanged
        ' altera a pagina atual do grid e vincula novamente
        dgClientes.CurrentPageIndex = e.NewPageIndex
        VinculaGrid()
    End Sub

Executando o projeto temos em um dado momento:

Até o próximo artigo ASP.NET ...