Caching em WebMethods

2008-08-23

O objecto Cache do System.Web.Caching é muito funcional e poderoso na gestão de dados aplicacionais no ASP.Net. Uso-o frequentemente em aplicações, como modo de persistir dados nas camadas superiores permitindo acelerar alguns processos, especialmente quando os dados vão ser usados continuamente durante um curto período de tempo e em diversas páginas ou com operações de paginação e exportação de dados de uma GridView.

Há naturalmente vantagens e desvantagens em usar a Cache do .Net para armazenar dados. A Cache é efectivamente rápida. Muito mais rápida que o ViewState, por exemplo, e faz uma melhor gestão de grandes quantidades de dados que a objecto de Session. Permite também gerir o tempo de vida e modo de remoção dos dados. No entanto, a cache está disponível a todos os utilizadores, pelo que é necessário ter algum cuidado a gerir as chaves usada para armazenar os valores, se bem que esta característica até é vantajosa em muitas situações.

Enquanto que em páginas (ou melhor, classes herdadas da classe Page) o objecto Cache está imediatamente disponível, o mesmo não é tão verdade para WebServices. WebServices permite algumas estratégias de Caching, sendo a principal a cache de saída (output caching), em que a resposta do WebMethod é armazenado em cache durante um determinado período. Por exemplo:

Irá devolver a mesma string durante os 60 segundos posterior à chamada, e determinado pelo uso de “CacheDuration=60” no atributo do WebMethod.

Mas e se quisermos utilizar a cache da mesma forma que é usada nas páginas, com recurso a métodos (estáticos?) para inserir e obter valores? Enquanto que escrever:

é válida nas classes das páginas, o mesmo não é verdade num WebMethod. Aliás, no VS, para que o IDE reconheça o objecto Cache, é necessário inserir a referencia ao System.Web.Caching, e mesmo assim os métodos não são disponibilizados pelo IDE. Instanciar a cache com algo do género

é válido quer no IDE, quer em runtime, qualquer tentativa de atribuir ou obter um valor usando cache.Get(…) ou cache.Insert(…) levantam excepções.

A solução passa emtão por ir buscar o objecto de Cache a outro local, nomeadamente ao HttpRuntime. Deste modo, no WebMethod, já é possivel inserir e obter valores dentro de um método (que não é necessáriamente a resposta do método) e persisti-lo para utilizar com outros métodos ou até outros utilizadores.

O código anterior é exemplo de como utilizar a Cache do HttpRuntime. No TestMethod() é armazenado um valor na cache, e considerando que este é executado antes do TestMethod2(), ao chamar o TestMethod2() o valor presente na cache será recuperada e retornada, permitindo persistir dados entre métodos, especialmente quando volumosos, e que pode evitar trocas de dados lentos entre camadas aplicacionais ou serviços.