2009-06-26 6 views
-1

J'ai un travailleur de fond qui peut être annulé. Les flux normaux s'interrompent lorsque la variable CancelPending devient true (en réponse à l'interaction de l'utilisateur sur l'interface utilisateur qui appelle worker.CancelAsynch()), des exceptions sont levées car si (puisque le flux normal est interrompu, beaucoup d'exception null ref Donc, quand le travailleur revient, je veux pouvoir distinguer les exceptions qui ont été levées lorsque le travailleur a été annulé (pour les ignorer silencieusement) à partir d'exceptions levées lorsque le travailleur n'a pas été annulé (pour les signaler à UI).Backgroundworker: exception lors de l'annulation

Mon code est le suivant (désolé pour le C#/vb mix ...):

La classe ouvrière:

Public Class ClassBaseGetObjectsWorker 
    Inherits System.ComponentModel.BackgroundWorker 


Protected Overrides Sub OnDoWork(ByVal e As System.ComponentModel.DoWorkEventArgs) 
     Try 

      Dim cpt As Int16 = 0 
      While cpt < 5 
       System.Threading.Thread.Sleep(1000) 
       cpt = cpt + 1 
       If CheckForCancellation() Then 
        'Simulating exception due to cancel 
        Throw New Exception("Exception du to cancel !") 
       End If 
      End While 

     Catch exc As Exception 
      e.Cancel = Me.CancellationPending 
      Throw exc 
     End Try 

    End Sub 
End Class 

Le rappel:

void setObjSetCollWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { 
    if (e.Cancelled) { 
     resultLabel.Text += "Canceled"; 
     //e.Error is selently ignored 
    } 
    else { 
     if (e.Error != null) { 
      //Reporting errors arising during normal (uncanceled) flow 
      throw e.Error.InnerException; 
     } 
     else { 
      //Worker process finished without error or being canceled. 
      updateUIAfterBackgroundJob(); 
     } 
    } 
} 

Ensuite, quand je fais worker.CancelAsynch(), e.Cancelled est mis à false (ce qui n'est pas ce que j'attendais) dans le rappel terminé. Si je commente "Trow exc" dans le worker, si je teste à nouveau, e.Cancelled est correctement défini sur true. Donc, quel est le moyen le plus propre d'obtenir l'information que je veux, c'est-à-dire: je veux savoir si l'exception apparaissant dans le gestionnaire terminé a été levée lorsque le travailleur était dans l'état annulationPending ou non.

(Désolé pour mon mauvais anglais)

+0

À quoi ressemble le code travaillé, et comment il gère l'annulation? – Thies

+0

Le worker est similaire au code de simulation ci-dessus: il passe par plusieurs niveaux d'appel de fonction, chacun effectuant des boucles qui se terminent si CancellationPending (vérifié par un délégué) devient true. Ces boucles et fonctions sorties prématurées conduisent à des exceptions qui sont "normales", compte tenu du fait que le flux est interrompu et le résultat sera rejeté. Pourquoi demandez-vous cela? – jfburdet

Répondre

0

Si la meilleure façon de structurer le code dans votre OnDoWork() - la mise en œuvre est de lancer une exception lorsque vous détectez annulation, procédez comme suit:

Créer une CancelException:

public class CancelException: Exception {} 

Throw ce CancelException lorsque vous constatez que l'annulation est en attente:

if(CheckForCancellation()) throw new CancelException(); 

Ajouter un try-catch autour du code dans votre OnDoWork() - Méthode:

protected override void OnDoWork(DoWorkEventArgs e){ 
    try{ 
    //... 
    } 
    catch(CancelException){ 
    // silently return 
    return; 
    } 
} 

De cette façon, votre code obéira au BackgroundWorker contrat (ce qui est de retour de OnDoWork() lorsque vous détectez en attente d'annulation , plutôt que de lancer une exception), et la propriété Canceled devrait maintenant être comme vous l'attendez

+0

Une alternative moins intéressante serait d'ajouter un membre public "WasCancelled" sur ma classe dérivée BackgroundWorker qui peut être définie sur true dans le bloc catch OnDoWork (Me.WasCancelled = Me.CancellationPending). Ce membre pourrait ensuite être utilisé dans le rappel terminé. – jfburdet

Questions connexes