2010-10-07 4 views
4

Je suis en train de faire petit projet passe-temps en C#, une langue que je ne sais pas bien, et ont trébuché sur les éléments suivants:Comment distinguer les différents types d'exceptions dans le gestionnaire d'événements BackgroundWorker.RunWorkerCompleted

Supposons que vous ayez une opération asynchrone implémenté en utilisant BackgroundWorker. Maintenant, s'il existe une exception, l'événement RunWorkerCompleted sera déclenché et RunWorkerCompletedEventArgs.Error sera non nul.

La méthode canonique est-elle la suivante pour gérer différents types d'exception? (Ici, tous les types d'exception sont frères et sœurs héritage WRT)

if (e.Error != null) 
{ 
    FirstKindOfException e1 = e as OneKindOfException; 
    SecondKindOfException e2 = e as SecondKindOfException; 
    ... 
    LastKindOfException en = e as LastKindOfException; 
    if (e1 != null) 
    { 
     ... 
    } 
    else if (e2 != null) 
    { 
     ... 
    } 
    ... 
    else 
    { 
     ... 
    } 
} 

Il fonctionne, mais ... il ne se sent pas droit.

Répondre

7

Vous pouvez utiliser is pour maintenir chaque test bien scope:

if (e.Error is FirstKindOfException) 
{ 
    ... 
} 
else if (e.Error is SecondKindOfException) 
{ 
    ... 
} 

(puis refondue si vous voulez des valeurs spéciales de l'exception)

Pour être honnête, cependant, il est assez rare que j'ai besoin de gérer lots de différents types d'exceptions. Dans la plupart des cas, il est bon de simplement récupérer (compenser) à un état connu et signaler l'erreur de manière appropriée. Généralement, je préfère tester les erreurs probables avant Je commence l'action, donc une exception est vraiment quelque chose d'exceptionnel.

+0

À droite, mais dans le code e1 et e2 doivent tous deux être e.Error. Rollback si vous n'êtes pas d'accord. –

+0

@Henk actully Je voulais juste "e" mais vous avez raison - c'était incorrect comme écrit. –

2

En utilisant l'opérateur is peut-être?

if (e is OneKindOfException) 
{ 
} 
else if (e is SecondKindOfException) 
{ 
} 
5

Utilisez le est opérateur:

if (e.Error is FirstKindOfException) { 
    //... 
} 
else if (e.Error is SecondKindOfException) { 
    //... 
} 
//etc.. 

Ou tout simplement couper court puisque vous ne savez pas comment gérer ces exceptions de toute façon. Si vous ne vous auriez pris dans le gestionnaire d'événements DoWork(), il n'y a pas d'essayer de les manipuler après l'état évaporation:

if (e.Error != null) throw new BackgroundTaskFailedException(e.Error); 
+0

La réimpression est mauvaise! La performance en souffre ... – Aliostad

+3

@Aliostad: le but est de ne pas intercepter les exceptions que vous ne savez pas gérer. Perf n'a vraiment pas d'importance, le programme va planter quelques millisecondes plus lentement. Si l'exception est récupérable, cela devrait être pris en compte dans DoWork(). –

+0

bien qu'il veut le gérer et empêcher le crash et c'est pourquoi il le vérifie. Je suis d'accord qu'il doit gérer dans le client et non dans le BackgroundWorker lui-même mais à la fin, comme je l'ai dit, habituellement pas de point de différenciation. – Aliostad

1

Oui, vous pouvez le faire, mais dépend vraiment de ce que vous êtes va faire avec tous ces types d'exception. Normalement, ceci ne sera montré qu'à l'utilisateur, il n'est donc pas nécessaire de vérifier le type de l'erreur.

Vous devez également garder à l'esprit qu'il est probable que le type de l'exception soit AggregateException - qui est le retour des opérations Task<T> - vous devez donc faire attention.

+0

Jamais entendu parler de AggregateException. Devrais-je m'inquiéter si je n'utilise que BackgroundWorker et non la tâche ? –

+0

Si vous utilisez la tâche , vous récupérez toujours AggregateException (qui contiendra le reste des exceptions). Je ne suis pas sûr de BackgroundWorker mais cela pourrait être la même chose.Mais si vous ne l'avez pas reçu, alors c'est bien et ne vous inquiétez pas. – Aliostad

Questions connexes