Si un bloc finalement lève une exception, que se passe-t-il exactement ?
Plus précisément, que se passe-t-il si l'exception est lancée à mi-chemin dans un bloc finally. Les autres instructions (après) de ce bloc sont-elles invoquées?
Je suis conscient que les exceptions se propageront vers le haut.
c#
exception
exception-handling
try-catch-finally
Jack Kada
la source
la source
Réponses:
Cette exception se propage de haut en bas et sera (peut) être gérée à un niveau supérieur.
Votre bloc finalement ne sera pas terminé au-delà du point où l'exception est levée.
Si le bloc finally s'exécutait lors du traitement d'une exception antérieure, cette première exception est perdue.
la source
ThreadAbortException
, alors le bloc finalement entier sera terminé en premier, car il s'agit d'une section critique.Pour des questions comme celles-ci, j'ouvre généralement un projet d'application console vide dans Visual Studio et j'écris un petit exemple de programme:
Lorsque vous exécutez le programme, vous verrez l'ordre exact dans lequel
catch
et lesfinally
blocs sont exécutés. Veuillez noter que le code dans le bloc finally après que l'exception est levée ne sera pas exécuté (en fait, dans cet exemple de programme, Visual Studio vous avertira même qu'il a détecté du code inaccessible):Remarque supplémentaire
Comme l'a souligné Michael Damatov, une exception au
try
bloc sera "mangée" si vous ne la gérez pas dans uncatch
bloc (intérieur) . En fait, dans l'exemple ci-dessus, l'exception renvoyée n'apparaît pas dans le bloc de capture externe. Pour rendre cela encore plus clair, regardez l'exemple légèrement modifié suivant:Comme vous pouvez le voir sur la sortie, l'exception interne est "perdue" (c'est-à-dire ignorée):
la source
finally
bloc sera (presque) toujours exécuté, cela vaut également dans ce cas pour le bloc finalement interne (essayez simplement le programme exemple vous-même (un bloc finalement ne sera pas exécuté dans le cas d'un non récupérable) exception, par exemple unEngineExecutionException
, mais dans ce cas, votre programme se terminera immédiatement de toute façon.)S'il y a une exception en attente (lorsque le
try
bloc a unfinally
mais pascatch
), la nouvelle exception remplace celle-là.S'il n'y a aucune exception en attente, cela fonctionne tout comme lancer une exception en dehors du
finally
bloc.la source
catch
bloc (ré) déclenche une exception.L'exception se propage.
la source
Extrait rapide (et plutôt évident) pour enregistrer "l'exception d'origine" (levée en
try
bloc) et sacrifier "finalement l'exception" (levée enfinally
bloc), au cas où l'original est plus important pour vous:Lorsque le code ci-dessus est exécuté, "Original Exception" se propage vers le haut de la pile d'appels et "Final Exception" est perdue.
la source
J'ai dû le faire pour intercepter une erreur en essayant de fermer un flux qui n'a jamais été ouvert en raison d'une exception.
si la requête Web a été créée mais qu'une erreur de connexion s'est produite pendant la
puis le finalement attraperait une exception en essayant de fermer les connexions qu'il pensait être ouvertes parce que le webRequest avait été créé.
Si finalement il n'y avait pas de try-catch à l'intérieur, ce code provoquerait une exception non gérée lors du nettoyage de webRequest
à partir de là, le code se terminerait sans gérer correctement l'erreur qui s'est produite et donc causer des problèmes pour la méthode d'appel.
J'espère que cela vous servira d'exemple
la source
Le fait de lever une exception alors qu'une autre exception est active entraînera le remplacement de la première exception par la deuxième (plus récente) exception.
Voici un code qui illustre ce qui se passe:
la source
Il y a quelques mois, j'ai également fait face à quelque chose comme ça,
Pour résoudre ce problème, j'ai créé une classe utilitaire comme
Et utilisé comme ça
mais si vous voulez utiliser des paramètres et renvoyer des types, c'est une autre histoire
la source
La façon dont les exceptions levées par CodeA et CodeB sont traitées est la même.
Une exception levée dans un
finally
bloc n'a rien de spécial, traitez-la comme la levée d' exception par le code B.la source
L'exception se propage et doit être gérée à un niveau supérieur. Si l'exception n'est pas gérée au niveau supérieur, l'application se bloque. L'exécution du bloc "enfin" s'arrête au point où l'exception est levée.
Qu'il y ait une exception ou non, le bloc "finalement" est garanti pour s'exécuter.
Si le bloc "finalement" est exécuté après qu'une exception s'est produite dans le bloc try,
et si cette exception n'est pas gérée
et si le bloc finalement lève une exception
Ensuite, l'exception d'origine qui s'est produite dans le bloc try est perdue.
Excellent article pour plus de détails
la source
Il lève une exception;) Vous pouvez intercepter cette exception dans une autre clause catch.
la source