2011-09-19 4 views
3

J'ai un exemple d'application WinForms qui utilise le composant BackgroundWorker. Cela fonctionne très bien mais quand j'appuie sur le bouton Cancel pour annuler le fil d'arrière-plan, il n'annule pas le fil. Lorsque j'appuie sur le bouton Cancel pour appeler la méthode .CancelAsync(), puis dans le gestionnaire d'événements RunWorkerCompletede.Cancelled La propriété reste toujours false. Je pense que lorsque je clique sur le bouton Cancel, il devrait être réglé sur vrai.C#, Travailleur d'arrière-plan

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    for (int i = 1; i <= 100; i++) 
    { 
     // Wait 100 milliseconds. 
     Thread.Sleep(100); 
     // Report progress. 
     if (backgroundWorker1.CancellationPending == true) 
     { 
      //label1.Text = "Cancelled by user."; 
      break; 
     } 

     backgroundWorker1.ReportProgress(i); 
    } 
} 

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
    // Change the value of the ProgressBar to the BackgroundWorker progress. 
    progressBar1.Value = e.ProgressPercentage; 
    // Set the text. 
    label1.Text = e.ProgressPercentage.ToString(); 
} 

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    if (e.Cancelled == true) 
    { 
     label1.Text = "Canceled!"; 
    } 
    else if (e.Error != null) 
    { 
     label1.Text = "Error: " + e.Error.Message; 
    } 
    else 
    { 
     label1.Text = "Done!"; 
    } 
} 

private void button2_Click(object sender, EventArgs e) 
{ 
    if (backgroundWorker1.WorkerSupportsCancellation == true) 
    { 
     // Cancel the asynchronous operation. 
     backgroundWorker1.CancelAsync(); 
    } 
} 

Répondre

7

La propriété est annulé encore faux parce que vous sortir de la boucle et permettent la fonction DoWork du BackgroundWorker pour mettre fin de façon normale. Vous ne dites jamais à votre composant backgroundworker que l'annulation en attente a été réellement acceptée.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    for (int i = 1; i <= 100; i++) 
    { 
     // Wait 100 milliseconds. 
     Thread.Sleep(100); 

     if (backgroundWorker1.CancellationPending) 
     { 
      e.Cancel = true; 
      break; 
     } 

     // Report progress. 
     backgroundWorker1.ReportProgress(i); 
    } 
} 

La distinction est importante, parce que parfois vous voudrez peut-être le travail rollback que vous avez déjà fait lorsque vous détectez la demande de CancellationPending, et il peut donc être un certain temps avant de finir réellement avec l'annuler.