Mostrar progresos con BackgroundWorker
Mayo 11, 2008
-Mediante la clase Thread.
-Mediante delegados asíncronos.
-Mediante el componente BackgroundWorker.
Se me ocurren diversas situaciones en la que cada uno puede ser más apropiado. Pero, si lo que queremos es mostrar el progreso de la tarea, la mejor opción es el componente BackgroundWorker. El componente BackgroundWorker tiene varias características que le hacen interesante; como puede ser la notificación del progreso y notificación de cancelación.
El ejemplo de código siguiente es un modo sencillo de dar soporte para cancelación y notificación del progreso de una tarea asíncrona.
| Nota: Este componente solo está disponible desde la versión 2.0 del Framework. |
Lo primero es arrastrar el componente a nuestra aplicación

Una vez que los hemos situado en el área de trabajo configuramos las siguientes propiedades:
WorkerReportsProgress = true
WorkerSupportsCancellation=true (solo en caso de querer dar soporte para cancelación)
Ahora definimos los eventos de cancelación, notificación y trabajo.
DoWork: Este evento es disparado al comienzo de la operación asíncrona y sera donde realicemos las tareas.
ProgressChanged: Este evento será disparado el notificar un progreso al componente.
RunWorkerCompleted: Este evento será disparado al terminar la operación asíncrona.
| Nota: Si desea acceder a un control desde la operación que este realizando el componente BackgroundWorker. Por ejemplo, mostrar el estado de progreso en un control Label, es más que aconsejable hacerlo desde el evento ProgressChanged, ya que la aplicación podria comportarse de forma inesperada. |
Ya podemos escribir el código que sera lanzado con cada evento.
C#
private void bwProgress_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 1; i <= 100; i++)
{
//Realiza una tarea
System.Threading.Thread.Sleep(100);
bwProgress.ReportProgress(i);
if (bwProgress.CancellationPending)
return;
}
}
private void bwProgress_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Notificar el progreso de la tarea
progressBar1.Value = e.ProgressPercentage;
lblInfo.Text = e.ProgressPercentage + “%”;
}
private void bwProgress_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Realizamos las operaciones que haya que realizar al terminar el progreso
lblInfo.Text = “Tarea terminada”;
btnCancelar.Enabled = false;
btnIniciar.Enabled = true;
progressBar1.Value = 0;
}
private void btnIniciar_Click(object sender, EventArgs e)
{
//Iniciamos el trabajo
if (!bwProgress.IsBusy)
{
bwProgress.RunWorkerAsync();
btnCancelar.Enabled = true;
btnIniciar.Enabled = false;
}
}
private void btnCancelar_Click(object sender, EventArgs e)
{
//Solicitamos la cancelación de la operación
bwProgress.CancelAsync();
}
VB
Private Sub bwProgress_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bwProgress.DoWork
For i As Integer = 1 To 100
”Realiza una tarea
System.Threading.Thread.Sleep(100)
bwProgress.ReportProgress(i)
If (bwProgress.CancellationPending) Then
Return
End If
Next
End Sub
Private Sub bwProgress_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bwProgress.ProgressChanged
‘Notificar el progreso de la tarea
progressBar1.Value = e.ProgressPercentage
lblInfo.Text = e.ProgressPercentage + “%”
End Sub
Private Sub bwProgress_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bwProgress.RunWorkerCompleted
”Realizamos las operaciones que haya que realizar al terminar el progreso
lblInfo.Text = “Tarea terminada”
btnCancelar.Enabled = False
btnIniciar.Enabled = True
progressBar1.Value = 0
End Sub
Private Sub btnIniciar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIniciar.Click
”Iniciamos el trabajo
If (Not bwProgress.IsBusy) Then
bwProgress.RunWorkerAsync()
btnCancelar.Enabled = True
btnIniciar.Enabled = False
End If
End Sub
Private Sub btnCancelar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancelar.Click
‘Solicitamos la cancelación de la operación
bwProgress.CancelAsync()
End Sub

Como hemos podido ver, el código es sencillo. Con unas pocas lineas podremos dar soporte estable a nuestras operaciones asíncronas.
Entry Filed under: Piensa en asíncrono. Etiquetas: asíncrono, BackgroundWorker, Componente, Progresos.
3 Comments Add your own
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed
1.
aquiles | Octubre 6, 2008 at 8:42 pm
Hola, todo bien con el código, pero cómo puedo hacer pra que me funcione mi progressbar cuando uso un método que no lleva ninguna iteración, me explico:
realizo una copia de la bd a un archivo plano, esto me toma regular tiempo, primero usaba hilos con una imagen gif de cargando, luego he adaptado el backgroundwork y bien, el problema es cuando deseo agregar el progressbar,
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
‘Notificar el progreso de la tarea
ProgressBar1.Value = e.ProgressPercentage
lblAvance.Text = e.ProgressPercentage + “%”
End Sub
este método no me trabaja para nada, y para tratar de completar el progressbar no puedo usar unfor porque yo no quiero que ese método se repita varias veces sólo una, gracias
2.
aquiles | Octubre 9, 2008 at 2:29 pm
Hola Andrés te envié un correo, espero lo hayas recibo, en todo caso si deseas te dejo parte de mi código. Avísame. Saludos.
3.
camilo | Octubre 9, 2009 at 11:16 pm
Me podrias enviar el codigo que le enviaste a andres tengo el mismo problema gracias