JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Detener un Timer de ASP.NET AJAX

Los temporizadores (Timer) de las extensiones de AJAX para ASP.NET son muy útiles. Nos permiten ejecutar una determinada tarea cada cierto tiempo, provocando postbacks de la página  (tanto completos, como parciales) en intervalos regulares. Un único Timer colocado en la página puede conseguir que se refresquen todos los UpdatePanels disponibles o cada uno de manera individual.

Lo habitual es colocarlos en la página y olvidarnos de ellos. Pero ¿qué pasa si queremos poder pararlos y activarlos a voluntad?

La cosa tiene más complicación de la que parece a simple vista. Lo primero que se nos ocurre a cualquiera es que, dado que tiene una propiedad Enabled para activarlo y desactivarlo bastará con establecerla en False para conseguir el efecto deseado. Si lo hacemos desde un postback asíncrono enviado desde dentro de un UpdatePanel, ni se notará en la página, ¿no?.

Lo malo de esta idea es que, simplemente, no funciona. El motivo es que en un refresco parcial de página, aunque se establezca la propiedad del temporizador, al retornar desde el servidor el cambio no se ve reflejado en el código JavaScript que controla el funcionamiento del mismo (un temporizador no es más que un simple setInterval() de JavaScript de los de toda la vida que provoca por código un refresco parcial de la página).

Entonces, para conseguirlo no nos queda más remedio que controlarlo desde el lado cliente, con JavaScript, lo cual tiene la ventaja añadida de que no es necesario un viaje al servidor para una cosa tan prosaica como esta, así que mejor.

Si observamos el código fuente del control Timer en lado cliente (basta con pulsar F12 en Internet Explorer y ver el código desde la pestaña Script) verás que tiene las siguientes definiciones en su prototipo:

Sys.UI._Timer.prototype = {
    get_enabled: Sys$UI$_Timer$get_enabled,
    set_enabled: Sys$UI$_Timer$set_enabled,
    get_interval: Sys$UI$_Timer$get_interval,
    set_interval: Sys$UI$_Timer$set_interval,
    get_uniqueID: Sys$UI$_Timer$get_uniqueID,
    set_uniqueID: Sys$UI$_Timer$set_uniqueID,
    dispose: Sys$UI$_Timer$dispose,
    _doPostback: Sys$UI$_Timer$_doPostback,
    _handleEndRequest: Sys$UI$_Timer$_handleEndRequest,
    initialize: Sys$UI$_Timer$initialize,
    _raiseTick: Sys$UI$_Timer$_raiseTick,
    _startTimer: Sys$UI$_Timer$_startTimer,
    _stopTimer: Sys$UI$_Timer$_stopTimer,
    _update: Sys$UI$_Timer$_update
}

Como podemos ver es posible hacer muchas cosas desde lado cliente, en concreto las interesantes son: ver/establecer si está habilitado o no, ver/establecer su intervalo, pararlo y ponerlo de nuevo en marcha.

Sabiendo esto tomar control sobre el timer es muy sencillo, basta con incluir este código JavaScript:

<script language="javascript" type="text/javascript">

var tmr = null;

   function ReferenciaTimer() { 
      if (tmr == null)
         tmr = $find("<%= Timer1.ClientID %>");
      return tmr;
   }

   function PararTimer() {
      ReferenciaTimer()._stopTimer();
   }

   function LanzarTimer() {
      ReferenciaTimer()._startTimer();
   }
</script>

Lo único que hago es obtener una referencia al control Timer usando su identificador de cliente (que se "inyecta" desde el servidor al generar la página gracias a una expresión <%= %> de ASP.NET) y la función especial de AJAX $find que sirve para obtener referencias a los componentes en el lado cliente. Luego para pararlo o ponerlo en marcha llamo los método _stopTimer o _startTimer del control JavaScript, que hemos visto en su propotipo. Si colocamos dos botones HTML normales y corrientes que llamen a estas dos funciones que acabo de definir:

   <input id="Button1" type="button" value="Parar Timer" onclick="PararTimer();" />
   <input id="Button2" type="button" value="Lanzar Timer" onclick="LanzarTimer();" />

¡Listo!

Con esto tenemos controlado el Timer y sin necesidad de ir al servidor para nada. Por supuesto podemo susar un código similar para cambiar o leer su intervalo de refresco o, incluso, para provocar manualmente un evento "tick" que lance el postback asociado al control.

He preparado un pequeño ejemplo práctico con todo lo explicado que puedes descargar desde aquí (3,11 KB)

¡Espero que te sea útil!

José Manuel Alarcón
Banner

Comentarios (4) -

José Mª Fueyo

Interesante ejemplo.
¿Y si, por ejemplo, quisiera configurar de forma dinámica no el arranque o la parada, sino el intervalo de disparo del evento tick del timer, o lo que es más, deshabilitarlo? tomando estas propiedades de una tabla de la base de datos, por ejemplo.
¡Gracias!

Responder

Hola Chema:

Pues nada, si te fijas tienes definiciones en JavaScript para leer y escribir la propiedad Interval del temporizador: get_interval y set_interval, y también para habilitarlo y deshabilitarlo (get_enabled y set_enabled), por lo que no revistiría mayor dificultad.

saludos

JM

Responder

no funciona

Responder

Spain José M. Alarcón

En realidad sí que funciona. Bájate el ejemplo y pruébalo para comprobarlo...

Seguro que has hecho algo mal.

Responder

Agregar comentario