2009-05-12 6 views
17

J'ai un arrière-plan qui exécute une longue tâche de base de données. Je veux montrer la barre de progression pendant que la tâche est en cours. D'une manière ou d'une autre, l'arrière-plan ne rapportera pas la progression de la tâche.L'arrière-plan ne signale pas la progression

C'est ce que j'ai:

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

Je fais cela en WPF, mais je suppose que cela ne fera pas une différence.

Merci à l'avance

+2

Si vous indentez votre code de quatre espaces lorsque vous saisissez (ou modifiez) votre question, il sera affiché avec indentation et mise en forme comme du code, plutôt que d'être mélangé dans un paragraphe et difficile à lire. –

+0

Vous ne semblez pas appeler la méthode .ReportProgress de BackgroundWorker - est-ce simplement parce que vous nous montrez du code simplifié? – Mike

+0

@Mike, je pense que c'est probablement la raison plutôt que l'édition d'un exemple. –

Répondre

30

Vous devez décomposer votre méthode DoWork en progression reportable, puis appeler ReportProgress.

Prenez par exemple les suivantes:

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 votre travail ne peut être prédéterminée, essayez d'ajouter vos propres pourcentages:

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

Belle programmation, mauvaise mathématique ;-) (int) (100.0/totalSteps * i) –

2

rapport tout progrès sur l'événement DoWork

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

cela fonctionne comme ceci

3

Vous devez appeler worker.ReportProgress (percentComplete) dans votre méthode DoWork. percentComplete doit être calculé en fonction du travail total. Par exemple:

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

Il est parfois difficile de partitionner un travail en plusieurs segments pour pouvoir signaler la progression. Malheureusement, le BackgroundWorker ne résout pas cela, vous devez le faire vous-même.

2

Les progrès doivent être envoyés à partir de l'événement en appelant DoWork la méthode ReportProgress sur BackgroundWorker. Dans votre cas, vous ne pouvez pas signaler de progression car tout le travail est effectué en dehors de la fonction DoWork. Vous pouvez uniquement signaler la progression avant et après l'appel de getdate(), mais pas pendant l'appel puisque le thread BackgroundWorker est occupé.

9

Modifier la WorkReportProgress propriété de l'objet BackgroundWorker à vrai soit dans la fenêtre de propriétés ou en code.

Questions connexes