Invocando páginas ASP.NET con procesos pesados y no morir en el intento (y II)

A petición de espinete escribo una segunda parte del artículo, en el que adjunto el código fuente de ejemplo con lo que se proponía en el artículo anterior.

En el código adjunto se pueden ver las siguientes clases:

  • Trabajador: Esta clase es la que tiene implementado el proceso pesado. En nuestro caso, simplemente irá desde un número especificado como mínimo hasta el máximo, esperando un segundo en cada iteración.
  • GestionTrabajadores: Esta clase es el singleton al que se refiere el artículo anterior. Se encarga de gestionar una tabla hash en la que las instancias de la clase Trabajador se identifican mediante un Guid.

Además, podemos ver que hay tres páginas en el proyecto Web:

  • Inicial.aspx: En esta página se crea una instancia de la clase Trabajador, se la inicializa, y se la añade a la clase GestionTrabajadores, tras haber creado un Guid para identificarla. Posteriormente se reenvía al usuario a la siguiente página, pasando el Guid de la petición actual.
  • EnProceso.aspx: En esta página se muestra el progreso de la petición actual. Si se detecta que la petición ha finalizado, se reenvía al usuario a la siguiente página.
  • Terminado.aspx: En esta página simplemente se muestra un mensaje que indica que el procesamiento ha finalizado.

Obviamente, las mejoras que se le pueden hacer a este ejemplo son innumerables, pero aquí dejo un par de ideas, a ver si alguien se anima y las realiza, aportándolas para la comunidad:

  • La página Inicial.aspx, en vez de notificar el GUID de la petición, podría enviarnos a la página EnProceso.aspx, y en esta página que se muestren los diferentes trabajos que hay en curso. Para ello bastaría con proporcionar un enumerador a la clase GestionTrabajadores para recorrer la tabla hash.
  • La página EnProceso.aspx podría utilizar AJAX para no tener que refrescarse cada dos segundos.

Bueno, pues esto es todo por hoy.

Saludos!

7 comentarios en “Invocando páginas ASP.NET con procesos pesados y no morir en el intento (y II)”

  1. Augusto!!
    Has pensado en como podría escalar esto, un sistema en el que se hicieran muchas peticiciones de este tipo implicaría altísimos costes de memoria, ten en cuenta los costes que tiene levantar un hilo para ese procesado y más teniendo en cuenta que es un entorno ASP y que tienes que jugar ya con el hilo de cada página y un Application Pool de ASP.NET…

  2. Buenas Unai!!!

    La verdad es que la escalabilidad de la solución no me la había planteado. En general, cuando se requiere un procesamiento pesado de este tipo, no sueles tener muchos corriendo a la vez… (por ejemplo el cálculo de un balance, o procesos mensuales, cosas por el estilo)

    Pese a todo, creo que tal y como está hecho el ejemplo, en principio los hilos de las páginas (los principales) morirán una vez hayan concluido su ejecución, y el hilo para el procesado es único para cada proceso pesado, de los cuales es probable que no hayan muchos.

    Si tenemos un sistema en el que vayamos a tener muchos procesos pesados corriendo concurrentemente, quizá no sea una buena solución el usar una aplicación ASP.NET, y me inclinaría por una aplicación tipo SmartClient, haciendo todo lo posible en el cliente (salvo lo que sea indispensable hacer en el servidor).

    ¿Cómo lo atacarías tú? 😉 (así yo también aprendo!)

  3. El problema es que levantar hilos tiene unos costes de memoria importantes por todo lo que ello requiere y tener muchos request podría afectar demasiado a tu aplicación, por ejemplo sería bastante simple hacerle ataques de denegación de servicio, además de lo que afectas al pool de objetos del Application Domain de IIS.
    Una posible solución si no quieres dejar esto sin ASP.NET es hacer el procesamiento asíncrono basándote por ejemplo en mensajería de MSMQ y que sea otro proceso el que capture los mensajes y elementos a procesar. Posteriormente se podría desde una página revisar si ese proceso está terminado o bien aún esta en la cola etc..etc…

    P.D:¿que te parece?
    Saludos
    Unai

  4. Me parece perfecto 😉

    Creo que me voy a tener que empollar el CLR via C# para ver las implicaciones de lo que uso tan alegremente (hilos, etc…)

    Gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *