Question

J'ai un travailleur d'arrière-plan 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 générées, car si le flux normal est interrompu, jeté)

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) des exceptions émises lorsque le travailleur n'a pas été annulé (pour les signaler à l'interface utilisateur).

Mon code est le suivant (désolé pour le mélange c # / vb ...):

La classe de travail:

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, lorsque je suis en train de worker.CancelAsynch (), e.Cancelled est défini sur false (ce qui n’est pas ce à quoi je m'attendais) dans le rappel Terminé. Si je commente & "Trow exc &"; dans le travailleur, si je teste Encore une fois, e.Cancelled est correctement défini sur true.

Alors, quel est le moyen le plus propre d’obtenir les informations que je veux, c’est: je veux savoir si l’exception apparaissant dans le gestionnaire terminé a été levée alors que le travailleur était dans l’état d’annulation annulé ou non.

(Désolé pour mon anglais médiocre)

Était-ce utile?

La solution

Si le meilleur moyen de structurer le code dans votre mise en œuvre OnDoWork () est de générer une exception lorsque vous détectez une annulation, procédez comme suit:

Créer une exception CancelException:

public class CancelException: Exception {}

Lancez cette exception CancelException lorsque vous détectez que l'annulation est en attente:

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

Ajoutez un try-catch autour du code dans votre méthode OnDoWork ():

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

De cette façon, votre code obéira au contrat BackgroundWorker (qui consiste à renvoyer OnDoWork () lorsque vous détectez une annulation en attente, plutôt que d'exécuter une exception), et la propriété Canceled devrait maintenant être conforme à vos attentes

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top