2009-05-12 12 views
17

Ho un lavoratore in background che esegue un'attività di database lungo. Voglio mostrare la barra di avanzamento mentre l'attività è in esecuzione. In qualche modo il lavoratore in background non segnalerà l'avanzamento dell'attività.Backgroundworker non segnalerà i progressi

Questo è quello che ho:

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; 
} 

sto facendo questo in WPF, ma credo che non farà la differenza.

Grazie in anticipo

+2

Se rientri il tuo codice di quattro spazi quando stai scrivendo (o modificando) la tua domanda, questa verrà visualizzata con rientro e formattazione come il codice, piuttosto che schiacciata insieme in un paragrafo e difficile da leggere. –

+0

Sembra che tu non stia chiamando il metodo .ReportProgress di BackgroundWorker - è semplicemente perché ci stai mostrando un codice semplificato? – Mike

+0

@ Mike, penso che sia probabilmente la ragione piuttosto che la modifica di un esempio. –

risposta

30

È necessario suddividere il metodo DoWork in avanzamento dichiarabile e quindi chiamare ReportProgress.

Prendiamo ad esempio la seguente:

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); 
    } 

} 

Se il lavoro non può essere predeterminato, prova ad aggiungere le proprie percentuali:

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

Bella programmazione, cattiva matematica ;-) (int) (100.0/totalSteps * i) –

2

appena segnalano progressi in caso DoWork

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

funziona così

3

È necessario chiamare worker.ReportProgress (percentComplete) nel metodo DoWork. percento Il completamento dovrebbe essere calcolato in base al lavoro totale. Per esempio:

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

A volte è difficile per dividere un lavoro in blocchi diversi per essere possibile per segnalare lo stato di avanzamento. Sfortunatamente il BackgroundWorker non risolve questo, devi farlo da solo.

2

progresso deve essere inviato dallo all'interno dell'evento DoWork chiamando il metodo ReportProgress su BackgroundWorker. Nel tuo caso, non puoi segnalare alcun progresso perché tutto il lavoro viene eseguito al di fuori della funzione DoWork. È possibile segnalare l'avanzamento prima e dopo la chiamata a getdate(), ma non durante la chiamata poiché il thread di BackgroundWorker è occupato.

9

Modificare il WorkReportProgress proprietà dell'oggetto BackgroundWorker a vero sia nella finestra delle proprietà o nel codice.