Arrêter le travailleur de fond

Mon application utilise un travailleur d’arrière-plan pour aller travailler dans une boucle. Je l’ai pour qu’à chaque itération de boucle, il vérifie si l’annulation en attente est vraie et si c’est le cas, éclate la boucle. Tout va bien, mon application arrête le traitement une fois terminée l’itération actuelle de la boucle. Le problème est que je pense que l’agent d’arrière-plan est toujours en cours d’exécution. Si je clique sur le bouton pour relancer le traitement, un message d’erreur indiquant que l’agent d’arrière-plan est occupé s’affiche.

J’allais me débarrasser du travailleur, mais il est créé lorsque le formulaire est exécuté. Si je le supprime, ce n’est pas là pour recommencer à travailler. Ce que je veux vraiment faire, c’est dire à l’agent d’arrière-plan qu’il est complet, si je clique sur un bouton ‘Arrêter le traitement’, il est prêt à recommencer le traitement lorsque je clique sur le bouton Démarrer!

J’allais essayer ceci:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { while (!backgroundWorker1.CancellationPending) { // Start processing in a background thread so the GUI remains responsive, // pass in the name of the text file produced by // PFDR FilenameLogic(txtLetterType.Text); } } 

Même réponse que Marc Gravell mais vous ne semblez pas suivre.

Définissez-vous e.cancel = true?

  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; i <= 10; i++) { if (worker.CancellationPending == true) { e.Cancel = true; break; } else { // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); worker.ReportProgress(i * 10); } } } 

Lorsque vous créez le travailleur, définissez worker.WorkerSupportsCancellation sur true . Désormais, dans le gestionnaire DoWork , vous devez DoWork périodiquement (au début, au début d’une boucle, etc.) worker.CancellationPending – s’il est vrai, définissez e.Cancel = true; (afin que vous puissiez distinguer l’achèvement de l’annulation), le nettoyage et la sortie ( return; ). Maintenant, votre bouton d’annulation peut appeler worker.CancelAsync(); et il agira de manière appropriée.

J’ai à peine trouvé un moyen agréable d’ annuler un Backgroundworker via un bouton Stop :

Mon application ressemble à ceci, deux boutons et une barre de progression:

entrez la description de l'image ici

Après avoir appuyé sur le bouton d’arrêt, il ressemble à ceci:

entrez la description de l'image ici

Pour la méthode de clic sur le bouton Démarrer, le code vérifie si le BGW est occupé. Si non, démarrez le BGW:

 private void btnStart_Click(object sender, EventArgs e) { //BGW if (!backgroundWorker1.IsBusy) { backgroundWorker1.RunWorkerAsync(); } } 

Le bouton d’arrêt appelle la méthode suivante, qui définit un indicateur AnnulationPendant sur true:

  private void btnStop_Click(object sender, EventArgs e) { backgroundWorker1.CancelAsync(); } 

Cet indicateur peut être utilisé dans la méthode backgroundWorker1 _DoWork , chargée du traitement des fonctions consommant beaucoup de temps:

 private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i <= 100; i++) { backgroundWorker1.ReportProgress(i); Thread.Sleep(100); if (backgroundWorker1.CancellationPending && backgroundWorker1.IsBusy) { e.Cancel = true; return; } } } 

Et vient maintenant la partie délicate, car avant de fermer le fil supplémentaire, vous devez vérifier l'object e dans le paramètre backgroundWorker1 _ProgressChanged s'il est annulé ou non !!!!! Sinon, vous obtiendrez une erreur .

 private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { int i = 0; if (!e.Cancelled) { i = (int)(e.Result); } else { i = 0; } // Check to see if an error occurred in the // background process. if (e.Error != null) { MessageBox.Show(e.Error.Message); return; } // Check to see if the background process was cancelled. if (e.Cancelled) { MessageBox.Show("Processing cancelled."); return; } // Everything completed normally. // process the response using e.Result MessageBox.Show("Processing is complete."); } 

Informations supplémentaires: N'oubliez pas de définir ces indicateurs Backgroundworker:

  //Set WorkerReportsProgress true - otherwise no ProgressChanged active backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; 

Si ce petit tutoriel était utile -> Thumb up

Il semble que j’ai résolu l’erreur. Dans la méthode Backgroundworker DoWork que j’ai mise pendant un certain temps, CancelPending n’est pas vrai et quand il est vrai, je règle e.Cancel = true. Cela semble maintenant fonctionner correctement!