[ASP.NET] Acelera tus WebSites con WebCache

Hola que tal, si bien no es nada nuevo esto de WebCache, he visto que es poco utilizado y realmente muy útil, pongámonos en la siguiente situación :

“Tienes una consulta a una fuente de datos, la cual tiene un tiempo de ejecución y/o de CPU considerable, los datos tienen una frecuencia de actualización de unos 30 minutos, por ejemplo un reporte del estado sobre algún proceso.”

Ahora bien, podríamos pensar en usar sesiones , con todo el costo en rendimiento y problemas de escalabilidad, pero ya que las sesiones son por usuario, cuando otro usuario, alguien que no ha ingresado a ver el reporte, lo haga, de todos modos deberá esperar, sin considerar que luego de 20min (tiempo de vida por defecto de las sesiones), el usuario que ya había ingresado, va a tener que esperar nuevamente. Entonces las sesiones no son una solución efectiva al problema.

Desde la versión 1.1 de ASP.NET (hace ya bastantes años, aunque se recomienda usarlo desde la versión 2) se implemente la Clase Cache, que nos permite persistir en memoria objetos, además nos permite definir la cantidad de tiempo que los datos van a persistir e implementar un callback para cuando la cache expira. Esta cache es compartida por todas las solicitudes al sitio, no solo por usuario.

Un pequeño extracto de código de una aplicación(modificado):

Private Sub getReporte()

  Dim dt As New DataTable

  If Cache.Item("datos") Is Nothing Then

      dt.ReadXml(Server.MapPath("Ventas2.xml"))

      Cache.Insert("datos", dt, Nothing, DateTime.Now.AddMinutes(30),
      TimeSpan.Zero, CacheItemPriority.Default, New CacheItemRemovedCallback
       (AddressOf ReportRemovedCallback))

   Else

       dt = DirectCast(Cache.Item("datos"), DataTable)

   End If

End Sub

Esta pequeña función obtiene los datos de un XML que es bastante extenso,(en realidad el código original hace referencia a un WebService que se demora bastante en responder, cerca que 20 segundos). Pero veamos en detalle:

  1. Primero que nada revisamos si los datos están en cache, con Cache.Item(key)
  2. Luego, en el caso que no estén en la cache, los vamos a buscar leyendo del xml normalmente, luego se insertan el cache con Cache.Insert y le damos un tiempo de vida a esta entrada en el cache de 30 minutos (AddMinutes(30)), también seteamos mediante un objeto CacheItemRemovedCallback la dirección del método (ReportRemovedCallback), esta es la función que se va a ejecutar cuando el cache expire.
  3. En el caso que ya tengamos los datos en el cache (según el paso 1), simplemente hacemos el casting para pasarlos a un datatable.

Ahora si vemos la función ReportRemoveCallback tenemos que llamamos nuevamente a la lectura del Reporte, generando nuevamente la llamada. Se lo que estás pensando, estoy se está generando todo el día independiente si se esta viendo realmente, bueno, esto lo puedes controlar programáticamente, es decir, programar para que el cache se vuelva a generar si estoy dentro de ciertas horas, todo depende de la frecuencia y horas en los que los usuarios consultas el reporte.

Public Sub ReportRemovedCallback(ByVal key As String, _

         ByVal value As Object, ByVal removedReason _

         As CacheItemRemovedReason)

        getReporte()

End Sub

En la práctica el cache compartido y la validación de la existencia de los datos en el mismo, hace que la experiencia de usuario al momento de leer el reporte se mejore bastante. En mi caso, esto era una llamada a un Web Service, que fácil se demoraba 20 segundos, y era consultado desde un teléfono Blackberry, ahora es prácticamente instantáneo y solo con utilizar esta excelente clase.

Espero que te sirva, a mi , ufff, bastante, y a los usuarios, mucho más.
Saludos!
Gonzalo

[Tips] HTML5 Input Number con Decimales

Hola, por problemas de tiempo no me podido actualizar el blog tanto como quiero, tengo varios articulos a medio escribir, pero ya inventaré algo para ausentarme del trabajo y tener tiempo para esto Sonrisa.

Ahora un pequeño tip, estoy desarrollando una Web Móvil y el usuario quiere ingresar numeros en un campo de texto HTML, para esto es perfecto el nuevo tipo de input que nos trae HTML5, el number y no es nada más que:

  <input type="number" name="ancho" id="ancho"  required  />

También podemos especificar el máximo y el mínimo de datos aceptados, así como además solo con agregar la propiedad Required, el navegador valida por nosotros que el usuario llene la caja de texto, genial!, pero había un problema, necesitaba que el usuario pudiese ingresar números decimales. Y el tema es muy simple, solo agregamos el step, que corresponde al incremento

<input type="number" step="0.01" name="ancho"  id="ancho" required autofocus />

Agregué el atributo autofocus, también muy útil, me imagino que no necesita mayor explicación este atributo. Sonrisa

image

Y listo!, así de sencillo, de hecho HTML5 está hecho para que las cosas que antes eran complicadas , ya no lo sean.

Saludos!
Chalalo

[NadaNuevo] Link Conversor de Código C# a Vb.NET y Viceversa

image

Hola, este link no tiene nada nuevo, jejejje. Me pongo el parche antes de la herida, lo que pasa es que varios alumnos me han preguntado lo mismo, así que les quería compartir un link con el que pueden convertir código de C# a Vb.NET y Viceversa, es una utilidad del team  de Telerik , seguro hay otros, pero creo que este esta bastante bueno. Ojo que no es solo un “conversor” de sintaxis, si tu código está incorrecto, no lo va a convertir, ya que compila a MSIL y luego pafff! , obtiene el código en c# o vb.net mediante reflector.

Está en Beta desde que lo conozco, pero bueno, hace el trabajo. La URL ES:

http://converter.telerik.com/

Eso, espero que les sirva.

[Tips] Solución rápida a la no generación de Métodos Begin y End en referencias a WebServices.

Hola, quería compartir este tip, me paso hace poco, y es que al hacer la referencia web a un XML Webservice no se generaron los métodos beginX… y endX… para le ejecución asyncrona (Puedes ver la documentación de esto acá:http://msdn.microsoft.com/en-us/library/tz4bkcx2%28v=vs.80%29.aspx)

Bueno, después de buscar y buscar, la solución que encontré, que quizas no es la más adecuada, pero me sirvió es la siguiente:

1) Modificar el archivo del proyecto y ubicarse bajo el tag <PropertyGroup>, para esto tienes que hacer unload de proyecto, o cierras el Visual Studio y editas el archivo .vbproj con el notepad (o el editor que prefieras)

2) Localizar la sección “PropertyGroup” que contiene la propiedad “ProjectGuid” y agregar la siguiente sección (lo puse de esta forma por tema de espacio)
<WebReference_EnableLegacyEventingModel>
   True
</WebReference_EnableLegacyEventingModel>

Si te marca un error, revisa que esté bien incluido, si todo está correcto, pero de todos modos te indica un error, graba y continuemos.

3) Guardar el archivo y volverlo a cargar en Visual Studio

5) Por último, generar nuevamente el proxy haciendo un update a la referencia web.

y Listo! se generaron los métodos que necesitaba Sonrisa

Espero que sea de ayuda,
Saludos
Chalalo

Nuevo Release de Ajax Control Toolkit–Sep2011

Ya es un poco antigua la noticia, pero de todos modos, te comento que la librería Ajax Control Toolkit tiene un nuevo release con interesantes cambios.

Acá hay un pequeño resumen, las imágenes las obtuve de la fuente de la noticia, el maestro Stephen Walther, en donde encontrarás en detalle la explicación del funcionamiento y uso de los nuevos controles:

http://stephenwalther.com/blog/archive/2011/09/27/september-2011-release-of-the-ajax-control-toolkit.aspx

Los cambios relevantes son:

Data ranges: Ahora cuando usamos el Calendar Extender, podemos especificar una fecha de inicio y fecha fin entre las cuales el usuario puede seleccionar. Esta es una característica muy solicitada en el sitio de Codeplex de ACT.

<asp:CalendarExtender
    ID="Calendar1"
    TargetControlID="txtHotelReservationDate"
    StartDate="3/2/2009"
    EndDate="5/16/2009"
    SelectedDate="3/2/2009"
    runat="server" />

image

Twitter Control: Al igual que el helper de WebMatrix, podemos mostrar los tweets asociados a una cuenta o a una búsqueda.

<asp:ToolkitScriptManager ID="tsm" runat="server" />
<asp:Twitter ID="Twitter1" ScreenName="shanselman" runat="server" />

image

Gravatar Control: Posibilidad de usar este nuevo control para mostrar una imagen única para cada usuario del sitio web.

<asp:ToolkitScriptManager ID="tsm" runat="server" />
<asp:Gravatar ID="Gravatar1"Email=”chalalo@hotmail.com” runat="server" />

image

Para descargar la ultima versión pueden ir a:

http://AjaxControlToolkit.CodePlex.com

Saludos!
Gonzalo