110 votes

Va Essayer / pour finir (sans les prises) bulle de l'exception?

Je suis presque certain que la réponse est OUI. Si j'utilise un essai bloc finally, mais ne pas utiliser un bloc Catch alors toutes les exceptions de la bulle. - Il Correct?

Toute réflexion sur la pratique en général?

Seth

125voto

Jon Skeet Points 692016

Oui, absolument. En supposant que votre finally bloc ne jette pas une exception, bien sûr, dans ce cas qui aura pour effet de "remplacer" celui qui a été initialement lancée.

59voto

Eric Lippert Points 300275

Toute réflexion sur la pratique en général?

Oui. Être prudent. Lorsque votre bloc finally est exécuté, il est tout à fait possible qu'il est en cours d'exécution en raison d'une prise en charge, inattendu, une exception a été levée. Cela signifie que quelque chose est cassé, et quelque chose de complètement inattendu peut se produire.

Dans cette situation, il est sans doute le cas que vous ne devriez pas exécuter le code dans enfin blocs. Le code dans le bloc finally peut être construit à supposer que les sous-systèmes dont il dépend sont en bonne santé, alors qu'en fait, ils pourraient être profondément brisé. Le code dans le bloc finally pourrait faire empirer les choses.

Par exemple, je vois souvent ce genre de chose:

DisableAccessToTheResource();
try
{
    DoSomethingToTheResource();
}
finally
{
    EnableAccessToTheResource();
}

L'auteur de ce code est de penser "je suis prise d'une mutation temporaire à l'état du monde; j'ai besoin de restaurer l'état de ce qu'il était avant, j'ai été appelé". Mais pensons à tous les moyens de ce qui pourrait aller mal.

Tout d'abord, l'accès à la ressource pourrait déjà être désactivé par l'appelant; dans ce cas, ce code réactive, peut-être prématurément.

Deuxièmement, si DoSomethingToTheResource déclenche une exception, est la bonne chose à faire pour permettre l'accès à la ressource??? Le code qui gère la ressource est interrompue de façon inattendue. Ce code affirme, en effet, "si le code de gestion est cassé, assurez-vous que d'autres codes peuvent appeler la ligne de code cassé dès que possible, de sorte qu'elle peut échouer horriblement trop." Cela semble être une mauvaise idée.

Troisièmement, si DoSomethingToTheResource déclenche une exception, alors, comment savons-nous que EnableAccessToTheResource ne sera pas aussi lever une exception? Quelle horreur s'est abattue sur l'utilisation de la ressource pourrait également affecter le code de nettoyage, dans lequel cas, l'exception sera perdu et le problème sera plus difficile à diagnostiquer.

J'ai tendance à écrire du code comme ça, sans utilisation de try-finally blocs:

bool wasDisabled = IsAccessDisabled();
if (!wasDisabled)
    DisableAccessToTheResource();
DoSomethingToTheResource();
if (!wasDisabled)
    EnableAccessToTheResource();

Aujourd'hui, l'état n'est pas muté à moins qu'il doit être. Maintenant l'appelant de l'état n'est pas foiré autour avec. Et maintenant, si DoSomethingToTheResource échoue, alors nous n'avons pas ré-autoriser l'accès. Nous supposons que quelque chose est profondément brisé et ne pas risquer d'aggraver la situation en essayant de garder le code en cours d'exécution. L'appelant de régler le problème, s'ils le peuvent.

Alors, quand est-ce une bonne idée d'exécuter un bloc finally? Tout d'abord, lorsque l'exception est prévue. Par exemple, vous pourrait s'attendre à ce qu'une tentative de verrouiller un fichier peut échouer, parce que quelqu'un d'autre l'a enfermé. Dans ce cas, il est logique d'intercepter l'exception et le rapport à l'utilisateur. Dans ce cas, l'incertitude sur ce qui est brisé est réduite; il est rare de faire empirer les choses par le nettoyage.

Deuxièmement, lorsque la ressource que vous êtes le nettoyage est à une pénurie de ressources système. Par exemple, il est logique de fermer un descripteur de fichier dans un bloc finally. (Une "aide" est bien sûr juste une autre façon d'écrire un essai bloc finally.) Le contenu du fichier peut être endommagé, mais il n'y a rien que vous pouvez faire à ce sujet. Le descripteur de fichier va être fermé, et donc elle pourrait tout aussi bien être plus tôt plutôt que plus tard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X