¿Cómo usar Caching en una aplicación Windows (WPF o WinForms)?
Visual Studio 2010 introduce muchas mejoras e interesantes características algunas de las cuales son extensiones de un «mundo» hacia el «otro«, y en el caso concreto de esta entrada, el uso de Caching que se hacía en Web a Windows, en aplicaciones de escritorio, con WPF o WinForms.
Hay momentos en el desarrollo Web, que nos interesa mantener datos o informaciones en caché, que por motivos determinados no nos interesa estar consultando constantemente.
Esa posibilidad se materializa en el ambiente Web gracias al objeto System.Web.Caching.Cache [http://msdn.microsoft.com/es-es/library/system.web.caching.cache.aspx].
El caso es que el trabajo con datos cacheados se hizo tan popular y necesario, que muchas aplicaciones Windows utilizan esta librería.
El problema es que se producía un mal uso del ensamblado System.Web.dll que debíamos referenciar para poder usar el objeto caché de ASP.NET, pero como digo, en un ambiente Windows, anti-natural si se me permite la expresión con el propósito del ensamblado que estaba diseñado para ser utilizado en un ambiente Web.
Funcionar funcionaba, ahora bien, no es la mejor práctica sin lugar a dudas, y muchas aplicaciones de escritorio la utilizan.
Por esa razón, la gente de Microsoft empezó a pensar en cómo crear objetos que permitieran de forma más liviana, ofrecer los mecanismos de cacheo que posee las aplicaciones Web en un ambiente Windows utilizando sus ensamblados.
Así, surgió el ensamblado System.Runtime.Caching.dll que es propio de .NET Framework 4.0 y que contiene dos clases principales.
La primera de esas clases tiene como misión abstraer los tipos con el fin de implementar tipos personalizados de caché.
La segunda de esas clases implementa en memoria un objeto de caché concreto a través de la clase System.Runtime.Caching.MemoryCache.
Quizás, la mejor forma de ver esto es haciendo un ejemplo práctico que nos muestre como trabajar con datos cacheados en una aplicación Windows, y así comprenderemos mucho mejor todo esto.
Iniciaremos una nueva aplicación Windows en C# con Visual Studio 2010 y agregaremos a la ventana tres controles Button y dos controles Label, tal y como se muestra a continuación:
Dentro de nuestra aplicación, deberemos realizar diferentes acciones.
Por un lado, agregaremos una referencia al ensamblado System.Runtime.Caching.dll.
Este ensamblado no se encuentra en la ventana de referencias de .NET, sino que deberemos ir a la ruta [C:WINDOWSMicrosoft.NETFrameworkv4.0.21006System.Runtime.Caching.dll] para seleccionarlo.
Una vez seleccionado, observaremos que el ensamblado aparece en las referencias con un icono de aviso.
Esto es debido a que la aplicación Windows por defecto, está como Microsoft .NET Framework 4 Client Profile, por lo que el ensamblado indicado no forma parte del paquete distribuible Clien Profile (para más información, ver la entrada anterior que escribí en mi blog sobre esto) y de ahí que salga el aviso en las referencias del proyecto.
Haremos clic con el botón derecho del ratón sobre el proyecto y seleccionaremos la opción Propiedades.
En las propiedades del proyecto, seleccionaremos como Target framework a «.NET Framework 4«.
Una vez hecho esto, Visual Studio 2010 nos avisará de que estamos cambiando la opción de distribución.
Indicaremos que sí, y seguiremos adelante.
Lo primero es que el ensamblado que aparecía con un icono de advertencia, ha desaparecido y podemos importar el namespace al proyecto y trabajar con sus clases y miembros.
Una vez que hemos llegado a este punto, nos focalizamos ya en el código de nuestra aplicación.
La primera acción será la de agregar nuestro namespace a la cabecera de la clase del formulario a través de la siguiente instrucción:
Finalmente, nos centraremos en el resto del código de nuestro ejemplo que es el que se indica a continuación:
/// Cargamos el formulario.
/// </summary>
/// <param name=»sender»></param>
/// <param name=»e»></param>
private void Form1_Load(object sender, EventArgs e)
{
// Inicializamos los controles Label a blanco.
this.label1.Text = «»;
this.label2.Text = «»;
} // Form1_Load /// <summary>
/// Creamos un objeto ObjectCache, y
/// referenciamos a MemoryCache.
/// </summary>
private ObjectCache cacheName = MemoryCache.Default; /// <summary>
/// Metodo para cargar los datos de cache de ejemplo.
/// </summary>
private void LoadCacheData()
{
// Mostramos el mensaje que indica que se estn cargando los datos de la cache.
this.label2.Text = «Cargamos los datos a la cache»;
// Declaramos un objeto para las politicas.
CacheItemPolicy policy = new CacheItemPolicy();
// Indicamos la prioridad de la politica.
policy.Priority = CacheItemPriority.Default;
// Preparamos un contenido para guardar en la cache.
string name = «Antonio « + DateTime.Now.ToString();
// Almacenamos el contenido anterior en la cache.
cacheName.Set(«name», name, policy);
} // LoadCacheData /// <summary>
/// Cargamos y mostramos los datos de cache.
/// </summary>
/// <param name=»sender»></param>
/// <param name=»e»></param>
private void button1_Click(object sender, EventArgs e)
{
// Obtenemos los datos de la cache.
string name = cacheName[«name»] as string;
// Si lo que obtenemos es nulo, es porque
// no hay datos cargamos en la cache.
if (name == null)
{
// No hay dados en la cache… => cargarmos los datos.
LoadCacheData();
}
// Mostramos el mensaje que indica que se muestran los datos de la cache.
this.label1.Text = «Mostramos los datos de la cache :: « + cacheName[«name»].ToString();
} // button1_Click /// <summary>
/// Eliminamos la cache.
/// </summary>
/// <param name=»sender»></param>
/// <param name=»e»></param>
private void button2_Click(object sender, EventArgs e)
{
// Eliminamos los datos de la cache.
cacheName.Remove(«name», null);
// Mostramos el mensaje que indica que se
// han eliminado los datos de la cache.
this.label1.Text = «Eliminamos los datos de la cache»;
this.label2.Text = «»;
} // button2_Click /// <summary>
/// Modificamos los valores de la cache.
/// </summary>
/// <param name=»sender»></param>
/// <param name=»e»></param>
private void button3_Click(object sender, EventArgs e)
{
// Preparamos un nuevo contenido para la cache.
string name = «Luis « + DateTime.Now.ToString();
// Preparamos una nueva politica para los datos de la cache.
CacheItemPolicy policy = new CacheItemPolicy();
// Establecemos la prioridad de la politica.
policy.Priority = CacheItemPriority.Default;
// Indicamos una expiracion de 5 segundos.
policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(5);
// Establecemos los valores nuevos de la cache con su politica nueva.
// La expiracion sera de 5 segundos.
// Pasados esos 5 segundos, el contenido de la cache se borrara.
cacheName.Set(«name», name, policy);
// Mostramos el mensaje que indica que los
// datos de la cache se han eliminado.
this.label1.Text = «Modificamos los datos de la cache (5 segundos para consultar)»;
this.label2.Text = «»;
} // button3_Click
Este ejemplo tiene como misión crear datos en la caché si no existen (primer botón), eliminar los datos de la caché (segundo botón), modificar/crear datos en la caché con una expiración de 5 segundos (tercer botón), pasados los cuales, los datos de la caché se eliminarán automáticamente. Si jugamos con estas tres opciones, comprenderemos mejor aún el comportamiento y funcionamiento de Caching.
Como podemos observar, el funcionamiento de System.Runtime.Caching es muy similar al Caching de System.Web, eso es así porque la gente de Microsoft ha querido hacer esto de forma que la gente que está familiarizada con el Caching de Web, no encuentre muchos cambios con respecto al nuevo ensamblado de Caching que ha creado Microsoft.
One Responseso far
Ta weno, weno, me gustaría ver qué ocurre, y como se gestiona este tipo de cachés en aplicaciónes windows que corren bajo entornos de servidor como Citrix, esa caché correría en el cliente ?, dependería de una supuesta sesión en el servidor ?? todo será mirarlo 🙂
Asias por el apunte Master 😉