Visual Basic .NET - BackgroundWorker + ProgressBar

Written by lopezatienza on 12 Abril 2010 – 9:38 -

Hola a todos.

En  este artículo voy a tratar de explicar mediante un proyecto de ejemplo, cómo hacer para realizar acciones de forma asíncrona con un objeto BackgroundWorker, para liberar la aplicación y que se pueda seguir trabajando sin que se quede bloqueada.

Esto es interesante cuando se precisa copiar archivos, enviar correos y otras acciones que requieren su tiempo.

Primeramente crearemos un proyecto de Windows Form.

 

Añadiremos los siguientes controles:

Button: btnIniciar

NumericUpDown: NumericUpDown1

TextBox: txtProgreso

ProgressBar: ProgressBar1

Label: lblEstado

BackgroundWorker: BackgroundWorker1

Debemos modificar la propiedad de BackgroundWorker.WorkerReportsProgress a True en tiempo de diseño, para poder reportar el progreso desde el worker.

Cabe destacar que no podremos acceder a los controles de la UI desde el evento DoWork, ya que el control BackgroudWorker se basa en Threads, y por lo tanto el acceso a un control de la UI puede provocar una excepción.

La mejor opción para poder modificar controles de la UI es acceder mediante Delegates,  se utilizan para implementar métodos de devolución de llamada (callbacks), esenciales para programar procesamiento asíncrono o insertar código de cliente.

El código asociado al Form sería el siguiente:

Public Class frmPrincipal

     Private cuenta As Integer = 100

     Private Sub btnIniciar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIniciar.Click

        Try

            Me.btnIniciar.Enabled = False

            cuenta = Me.NumericUpDown1.Value

            Me.BackgroundWorker1.RunWorkerAsync()

        Catch ex As Exception

            MessageBox.Show("Excepción controlada: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

        End Try

    End Sub

     Delegate Sub AddNumeroDelegate(ByVal number As Integer)

     Private Sub AddNumero(ByVal number As Integer)

        If txtProgreso.InvokeRequired Then

            txtProgreso.Invoke(New AddNumeroDelegate(AddressOf AddNumero), number)

        Else

            txtProgreso.AppendText("Elemento " & (number + 1).ToString() & " procesandose.." + Environment.NewLine)

        End If

    End Sub

 

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

        Try

            Dim i As Integer

            While i < cuenta

                BackgroundWorker1.ReportProgress(100 * i / cuenta, "Procesando (" & i & "/" & cuenta & ") elementos...")

                AddNumero(i)

                Threading.Thread.Sleep(100)

                i += 1

            End While

            BackgroundWorker1.ReportProgress(100, "Completado!")

            e.Result = True

        Catch ex As Exception

            e.Result = False

        End Try

    End Sub

     Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

        Try

            Me.btnIniciar.Enabled = True

        Catch ex As Exception

            Me.btnIniciar.Enabled = True

            MessageBox.Show("Excepción controlada: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

        End Try

    End Sub

     Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

        Try

            ProgressBar1.Value = e.ProgressPercentage

            lblEstado.Text = e.UserState

        Catch ex As Exception

            MessageBox.Show("Excepción controlada: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)

        End Try

    End Sub

 End Class

Espero que os sirva de ayuda.

Un saludo.

Descargar el proyecto VS2005

pass: lopezatienza.es


Tags:
Posted in Visual Basic .NET |

Leave a Comment

RSS