Y a-t-il des situations où il est approprié d'utiliser un bloc try-finally
sans bloc catch
?
Y a-t-il une bonne raison de faire cela ? Cacher les exceptions n'est-il pas une très mauvaise pratique!?
Y a-t-il des situations où il est approprié d'utiliser un bloc try-finally
sans bloc catch
?
Vous l'utiliseriez pour vous assurer que certaines actions se produisent après le contenu de try
ou sur une exception, mais lorsque vous ne souhaitez pas consommer cette exception.
Pour être clair, cela ne cache pas les exceptions. Le bloc finally
est exécuté avant que l'exception ne soit propagée dans la pile d'appels.
Vous l'utiliseriez également involontairement lorsque vous utilisez le mot-clé using
, car cela se compile en un try-finally
(ce n'est pas une conversion exacte, mais pour l'argument, cela suffit).
try
{
EssayerDuCodeQuiPourraitLancerUneException();
}
finally
{
NettoyerMemeEnCasEchec();
}
Le code s'exécutant dans finally
n'est pas garanti de s'exécuter, cependant le cas où il n'est pas garanti est assez rare - je ne m'en souviens même pas. Tout ce dont je me souviens, c'est que si vous êtes dans ce cas, il est très probable que ne pas exécuter le finally
n'est pas votre plus gros problème :-) donc en gros, ne vous inquiétez pas.
Mise à jour de Tobias: finally
ne s'exécutera pas si le processus est tué.
Mise à jour de Paddy: Conditions when finally does not execute in a .net try..finally block
L'exemple le plus courant que vous pourriez rencontrer est la libération d'une connexion de base de données ou d'une ressource externe même si le code échoue :
using (var conn = new SqlConnection("")) // Ignorez le fait que nous utilisons probablement un ORM ;-)
{
// Faire des choses.
}
Se compile en quelque chose comme :
SqlConnection conn;
try
{
conn = new SqlConnection("");
// Faire des choses.
}
finally
{
if (conn != null)
conn.Dispose();
}
Y a-t-il une bonne raison de faire cela ? Cacher les exceptions n'est-il pas une très mauvaise pratique!?
@AnthonyBlake L'exception n'est pas cachée. Si une exception s'est produite, elle exécuterait enfin et propagerait ensuite l'exception vers le haut de la pile d'appels.
En ce qui concerne le cas limite, le bloc finally ne sera pas exécuté si le processus est tué (avec "terminer le processus" dans le gestionnaire de tâches ou en cas de panne de courant, par exemple).
Bonne explication utilisant du code:
void MyMethod1()
{
try
{
MyMethod2();
MyMethod3();
}
catch(Exception e)
{
//faire quelque chose avec l'exception
}
}
void MyMethod2()
{
try
{
//effectuer des actions nécessitant un nettoyage
}
finally
{
//nettoyer
}
}
void MyMethod3()
{
//faire quelque chose
}
Si MyMethod2 ou MyMethod3 lance une exception, elle sera capturée par MyMethod1. Cependant, le code de MyMethod2 doit exécuter du code de nettoyage, par exemple fermer une connexion de base de données, avant que l'exception ne soit transmise à MyMethod1.
utilisation
est équivalent à try-finally
. Vous n'utiliserez try-finally
que lorsque vous voudrez effectuer un nettoyage à l'intérieur de finally
et que vous ne vous soucierez pas de l'exception.
La meilleure approche sera
try
{
using(resource)
{
//Faire quelque chose ici
}
}catch(Exception)
{
//Gérer l'erreur
}
En faisant cela, même si le nettoyage appelé par utilisation
échoue, votre code ne plantera pas.
Il y a certaines conditions où finally
ne sera pas exécuté.
StackOverflowException
ou une ExecutingEngineException
.Si vous avez, par exemple, une ressource non gérée que vous créez et utilisez dans le bloc try, vous pouvez utiliser le bloc finally pour vous assurer que vous libérez cette ressource. Le bloc finally sera toujours exécuté malgré ce qui se passe (par exemple, des exceptions) dans le bloc try.
Par exemple, l'instruction lock(x) se traduit vraiment par :
System.Threading.Monitor.Enter(x);
try { ... }
finally
{
System.Threading.Monitor.Exit(x);
}
Le bloc finally sera toujours appelé pour garantir que le verrou exclusif est libéré.
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.
2 votes
Sur MSDN, consultez try-finally (C# Référence). Notez que l'article fait référence à l'utilisation combinée de
try
etfinally
comme "try-finally déclaration."