119 votes

Utilisez un bloc « try-finally » sans bloc « catch »

Y a-t-il des situations où il est approprié d'utiliser un bloc try-finally sans bloc catch ?

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 et finally comme "try-finally déclaration."

181voto

Adam Houldsworth Points 38632

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();
}

0 votes

Y a-t-il une bonne raison de faire cela ? Cacher les exceptions n'est-il pas une très mauvaise pratique!?

21 votes

@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.

2 votes

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).

12voto

donstack Points 404

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.

http://forums.asp.net/t/1092267.aspx?Try+without+Catch+but+with+finally+doesn+t+throw+error+Why+no+syntax+error+

2 votes

Un exemple de ce "nettoyage" pourrait être saveLogFile(), que j'ai souvent envie de placer à la toute fin d'un programme peu importe quoi.

5voto

Amar Palsapure Points 7025

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é.

  • S'il y a une StackOverflowException ou une ExecutingEngineException.
  • Le processus est tué par une source externe.

4voto

Jeb Points 1749

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é.

1voto

Mitch Wheat Points 169614

Try/finally : lorsque vous ne voulez pas gérer les exceptions mais que vous souhaitez vous assurer que certaines actions se produisent que des exceptions soient lancées ou non par le code appelé.

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