Mostrar progresos con BackgroundWorker
mayo 11, 2008 at 8:46 pm 6 comentarios
-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.
Entrada archivada en:Piensa en asíncrono. Etiquetas:asíncrono, BackgroundWorker, Componente, Progresos.
6 comentarios Añade el tuyo
Deja un comentario
Trackback este articulo | Suscríbete a los comentarios vía RSS Feed
1.
aquiles | octubre 6, 2008 a las 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 a las 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 a las 11:16 pm
Me podrias enviar el codigo que le enviaste a andres tengo el mismo problema gracias
4.
Alikornio | agosto 4, 2010 a las 10:59 am
Buenas
Se trata de varios accesos a bases de datos y una barra de progreso que quiero que se muestre mientras tanto.
El problema, es el mismo que el de aquiles, se trata de hacerlo todo de un tirón, sin iteraciones, y al introducir este proceso en el backgroundWorker1_DoWork() no muestra la barra de proceso y en mi datagridview solo me muestra la primera linea, cuando el proceso fuera de dicho método funciona correctamente.
Gracias
5.
Alikornio | agosto 12, 2010 a las 9:29 am
Bueno ya consegui que la barra se mostrara, pero lo que me gustaría conseguir que es fuera una barra de progreso, pues la tengo puesta de las que “rebotan”.
El problema está en qué momento aumentar el tamaño de la barra, pues el trabajo es interno.
Gracias
6.
Brale | enero 31, 2011 a las 5:18 pm
Pichones VB — > e.ProgressPercentage & “%”