2009-05-12 19 views
17

Tengo un trabajador en segundo plano que ejecuta una tarea de base de datos larga. Quiero mostrar la barra de progreso mientras la tarea se está ejecutando. De alguna manera, el trabajador de segundo plano no informará el progreso de la tarea.Backgroundworker no informará el progreso

Esto es lo que tengo:

BackgroundWorker _bgwLoadClients; 

_bgwLoadClients = new BackgroundWorker(); 
_bgwLoadClients.WorkerReportsProgress = true; 
_bgwLoadClients.DoWork += new DoWorkEventHandler(_bgwLoadClients_DoWork); 
_bgwLoadClients.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bgwLoadClients_RunWorkerCompleted); 
_bgwLoadClients.ProgressChanged += new ProgressChangedEventHandler(_bgwLoadClients_ProgressChanged); 
_bgwLoadClients.RunWorkerAsync(parms); 

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e) 
{ 
    DataTable dt = getdate(); 
    e.Result = dt; 
} 

void _bgwLoadClients_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    progressBar1.Value = e.ProgressPercentage; 
} 

estoy haciendo esto en WPF, pero supongo que no hará una diferencia.

Gracias de antemano

+2

Si sangra su código en cuatro espacios cuando está escribiendo (o editando) su pregunta, se mostrará con sangría y formateándose como código, en lugar de mezclarse en un párrafo y es difícil de leer. –

+0

Parece que no está llamando al método .ReportProgress del BackgroundWorker, ¿es simplemente porque nos está mostrando un código simplificado? – Mike

+0

@Mike, creo que esa es probablemente la razón más que la edición excesiva de un ejemplo. –

Respuesta

30

Debe desglosar su método DoWork en el progreso reportable y luego llamar a ReportProgress.

Tomemos como ejemplo el siguiente:

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // If possible, establish how much there is to do 
    int totalSteps = EstablishWorkload(); 

    for (int i=0; i<totalSteps; i++) 
    { 
     // Do something... 

     // Report progress, hint: sender is your worker 
     (sender as BackgroundWorker).ReportProgress((int)(100/totalSteps)*i, null); 
    } 

} 

Si su trabajo no se puede predeterminar, trate de añadir sus propios porcentajes:

private void Something_DoWork(object sender, DoWorkEventArgs e) 
{ 
    // some work 

    (sender as BackgroundWorker).ReportProgress(25, null); 

    // some work 

    (sender as BackgroundWorker).ReportProgress(50, null); 

    // some work 

    (sender as BackgroundWorker).ReportProgress(60, null); 

    // some work 

    (sender as BackgroundWorker).ReportProgress(99, null); 
} 
+6

Programación agradable, mala matemática ;-) (int) (100.0/totalSteps * i) –

2

solo informe de situación sobre caso DoWork

private void _bgwLoadClients_DoWork(object sender, DoWorkEventArgs e) { 
    int progresValue0to100 = 75; 
    (sender as System.ComponentModel.BackgroundWorker).ReportProgress(progresValue0to100); 
    //do your jobs.. 
} 

funciona de la siguiente

3

Debe llamar a worker.ReportProgress (percentComplete) en su método DoWork. percentComplete debe calcularse en función del trabajo total. Por ejemplo:

for(int i =0; i != 100; i++) { 
    // do something 
    worker.ReportProgress(i); 
} 

A veces es difícil dividir un trabajo en varios fragmentos para poder informar el progreso. Desafortunadamente, el BackgroundWorker no resuelve esto, tienes que hacerlo tú mismo.

2

El progreso debe ser enviado desde dentro del evento DoWork llamando el método ReportProgress en el BackgroundWorker. En su caso, no puede informar ningún progreso porque todo el trabajo se está realizando fuera de la función DoWork. Solo puede informar el progreso antes y después de la llamada a getdate(), pero no durante la llamada, ya que el subproceso BackgroundWorker está ocupado.

9

Modificar la WorkReportProgress propiedad del objeto BackgroundWorker a cierto ya sea en la ventana de propiedades o en el código.

Cuestiones relacionadas