2009-10-16 5 views
17

Supposons que vous avez le code suivant:Gestion des exceptions: est finalement exécuté après le lancement?

Au lieu de faire:

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 

    ' 
    ' Clean up-code that gets not reached because exception 
    ' 
Catch e As Exception 
    ' 
    'Clean up initialized objects 
    ' 

    Throw e 
End Try 

Je voudrais faire:

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 
Catch e As Exception 
    Throw e 
Finally 
    ' 
    'Clean up initialized objects 
    ' 
End Try 

Ma question est simple: Dans le cas d'une exception est la enfin bloc atteint même s'il y a un lancer quelques lignes avant?

[EDIT] Merci pour vos réponses rapides.

Dans la première ligne il y aura NullReference-, COM- et FileNotFound-Exceptions je pense.

Ok, je vais aller pour ce code:

Try 
    ' 
    ' Initialize some objects 
    ' 

    ' 
    ' do something that fails 
    ' 
Catch e As Exception  ' or just "Catch"??   
    Throw 
Finally 
    ' 
    'Clean up initialized objects 
    ' 
End Try 

Bonne chance!

Inno

+2

Vous ne devriez pas écrire 'Throw e' mais simplement' Throw'. Sinon, vous réinitialisez la trace de pile d'exception, de sorte que vous perdez les informations sur l'endroit où l'exception a été soulevée initialement –

Répondre

25

Ma question est simple: Dans le cas d'une exception est le bloc finally atteint même s'il y a un jet quelques lignes avant?

Oui. Le Finally block est toujours1) exécuté et existe précisément pour le nettoyage. Dans votre code, supprimez le bloc Catch, il ne fait rien. Pire, il détruit en fait la trace de la pile car vous ne relancez pas l'exception originale, vous en lancez une nouvelle.

Si vous avez vraiment besoin d'un bloc Catch qui puis re-lève l'exception, utilisez les touches suivantes:

Catch e As XyzException 
    ' … do some stuff. ' 
    Throw 
End Try 

1): caveat emptor: il y a quelques exceptions comme StackOverflowException (comment montage ...) qui nécessitent une attention particulière et ne peuvent pas déclencher le bloc Finally. Les manipuler correctement est généralement assez difficile.

+1

Konrad - Enfin n'est pas toujours exécuté. Il ne sera pas exécuté lorsque vous avez une exception OutOfMemoryException par exemple. –

+0

@Pete: à droite, mais ce sont des cas de bords spécifiques (mais j'aurais dû les mentionner). –

+1

@Pete: Ne voulez-vous pas dire StackOverflowException? Il est facile de faire un test où finalement est exécuté en cas d'exception OutOfMemoryException. –

0

Oui c'est le cas, enfin est exécuté dans tous les cas. (il n'y a que quelques exceptions - Response.Redirect et certains cas avec multithreading)

5

Non, cela n'est PAS garanti. Il y a certaines exceptions - par exemple StockOverflowException et OutOfMemoryException - où l'exécution d'un bloc finally n'est pas garantie.

1

Dans presque tous les cas, un Final s'exécutera dans un bloc Try/Catch (exceptions notables, y compris lorsqu'une exception StackOverflowException ou OutOfMemoryException se produit). Je suis curieux cependant, pourquoi vous ne l'avez pas essayé par vous-même. Une façon précieuse d'apprendre des choses est de les essayer par vous-mêmes - après tout, vous pourriez finir par accepter une réponse qui est fausse ou trompeuse, et vous travaillerez sous ce mensonge à partir de ce moment.

+1

J'ai essayé mais mon débogueur s'est arrêté au lancer. J'ai lu la documentation et n'ai pas trouvé d'indice pour ma question. J'ai posé ces questions pour obtenir des réponses appartenant directement à ma question et y appartenant indirectement (comme des allusions comme "enfin est dans des circonstances particulières non exécutées"). – Inno

1

REMARQUE: La méthode System.Environment.FastFail a été exécutée immédiatement sur le processus/thread en cours, sans exécuter les sections finally.