Posteado por: toniogago | 15 diciembre 2009

Realizar un proceso batch con asp.net


En algunas aplicaciones web necesitamos realizar procesos que pueden durar bastante tiempo y la página nos devuelve un error de TimeOut. Estos procesos se suelen denominar batch o por lotes.

Pongamos un ejemplo

Protected Sub CmdIniciar_Click(ByVal Sender As Object, ByVal e as System.EventArgs) Handles CmdIniciar.Click
    'Espera 91 segundos. Por defecto ASP.NET el TimeOut son 90 S.
    Thread.Sleep(91000)
    'Para utilizar Thread debe estar importado System.Threading
End Sub


En este caso si el TimeOut está en 90 segundos, la página nos devolverá un error.

El proceso Batch
Para solucionarlo he utilizado un ThreadStart y un Thread de la siguiente forma:

Protected Sub CmdIniciar_Click(ByVal Sender As Object, ByVal e as System.EventArgs) Handles CmdIniciar.Click
    Dim ts as ThreadStart = New ThreadStart(AddressOf Espera)
    Dim Trabajo as Thread = New Thread(ts)
    Trabajo.Start()
End Sub
Private Sub Espera()
    Thread.Sleep(91000)
End Sub

El problema que tengo ahora es que no sé si el proceso batch termina correctamente ya que se ejecuta como un proceso aparte y el usuario no se entera.

Clases compatidas
La solución a este segundo problema la solventé con una clase compartida. Se pueden crear clases reutilizables guardándolas en una carpeta denominada App_Code. Al crear un nuevo elemento en el proyecto de tipo clase, Visual Studio nos avisa de ello:

Nueva clase en App_Code

Podeis encontrar más información en Microsoft.

El código de la clase sería:

Public Class TrabajoBatch
    Private Shared _Procesando As Boolean = False
    Private Shared _Mensaje As String = ""
    Public Shared ReadOnly Property Procesando() As Boolean
        Get
            Return _Procesando
        End Get
    End Property
    Public Shared Property Mensaje() As String
        Get
            Mensaje = _Mensaje
        End Get
        Set(ByVal value As String)
            _Mensaje = value
        End Set
    End Property
    Public Shared Sub Procesar()
        _Procesando = True
        _Mensaje = ""
    End Sub
    Public Shared Sub Terminado()
        _Procesando = False
        _Mensaje = ""
    End Sub
End Class

Ahora podemos modificar la página con el siguiente código:

Protected Sub CmdIniciar_Click(ByVal Sender As Object, ByVal e As System.EventArgs) Handles CmdIniciar.Click
        Dim ts As ThreadStart = New ThreadStart(AddressOf Espera)
        Dim workerThread As Thread = New Thread(ts)
        workerThread.Start()
End sub
Private Sub Espera()
    TrabajoBatch.Procesar()
    TrabajoBatch.Mensaje = "Trabajo iniciado."
    Thread.Sleep(91000)
    TrabajoBatch.Terminado()
    TrabajoBatch.Mensaje = "Finalizado."
End Sub

Añadimos a la página un control timer y una etiqueta para comprobar cada cierto tiempo el estado del trabajo, y en el evento Tick ponemos lo siguiente:

    Protected Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        lblTexto.Text = TrabajoBatch.Mensaje
    End Sub

Como el control timer genera un Postback, tendremos que poner en el evento Page_Load lo siguiente:

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Timer1.Interval = 1000
            Timer1.Enabled = False
        End If
        If TrabajoBatch.Procesando Then
            CmdIniciar.Enabled = False
            Timer1.Enabled = True
        Else
            CmdIniciar.Enable = True
            Timer1.Enabled = False
        End If
    End Sub

Tal como lo tenemos ahora, el usuario pulsará el botón Iniciar y el proceso en batch empezará deshabilitando el botón hasta que termine.
Hay que tener cuidado en el proceso e intentar capturar los posibles fallos ya que si esto ocurre el usuario tendrá la impresión que el trabajo no termina.

Un saludo

Anuncios

Responses

  1. Buen aporte. Me sirvió de mucho. Saludos!


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Categorías

A %d blogueros les gusta esto: