Tout ce qui est à l'intérieur des blocs finalement est exécuté (presque) toujours, alors quelle est la différence entre y inclure du code ou le laisser non fermé?
Tout ce qui est à l'intérieur des blocs finalement est exécuté (presque) toujours, alors quelle est la différence entre y inclure du code ou le laisser non fermé?
Réponses:
Le code à l'intérieur d'un bloc finally sera exécuté indépendamment du fait qu'il y ait ou non une exception. Ceci est très pratique lorsqu'il s'agit de certaines fonctions d'entretien ménager dont vous avez besoin pour toujours fonctionner comme la fermeture de connexions.
Maintenant, je suppose que votre question est de savoir pourquoi vous devriez faire ceci:
try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}
Quand vous pouvez faire ceci:
try
{
doSomething();
}
catch
{
catchSomething();
}
alwaysDoThis();
La réponse est que souvent, le code de votre instruction catch renverra une exception ou sortira de la fonction actuelle. Avec ce dernier code, le "alwaysDoThis ();" call ne s'exécutera pas si le code à l'intérieur de l'instruction catch émet un retour ou lève une nouvelle exception.
La plupart des avantages de l'utilisation de try-finally ont déjà été soulignés, mais j'ai pensé ajouter celui-ci:
try
{
// Code here that might throw an exception...
if (arbitraryCondition)
{
return true;
}
// Code here that might throw an exception...
}
finally
{
// Code here gets executed regardless of whether "return true;" was called within the try block (i.e. regardless of the value of arbitraryCondition).
}
Ce comportement le rend très utile dans diverses situations, en particulier lorsque vous devez effectuer un nettoyage (disposer des ressources), bien qu'un bloc d' utilisation soit souvent préférable dans ce cas.
chaque fois que vous utilisez des requêtes de code non gérées comme des lecteurs de flux, des requêtes de base de données, etc. et vous voulez attraper l'exception, puis utilisez try catch enfin et fermez le flux, le lecteur de données, etc. enfin, si vous ne le faites pas quand il y a des erreurs, la connexion ne se ferme pas, c'est vraiment mauvais avec les requêtes db
SqlConnection myConn = new SqlConnection("Connectionstring");
try
{
myConn.Open();
//make na DB Request
}
catch (Exception DBException)
{
//do somehting with exception
}
finally
{
myConn.Close();
myConn.Dispose();
}
si vous ne voulez pas attraper l'erreur, utilisez
using (SqlConnection myConn = new SqlConnection("Connectionstring"))
{
myConn.Open();
//make na DB Request
myConn.Close();
}
et l'objet de connexion sera supprimé automatiquement s'il y a une erreur, mais vous ne capturez pas l'erreur
Parce que finally sera exécuté même si vous ne gérez pas d'exception dans un bloc catch.
Enfin, les instructions peuvent s'exécuter même après le retour.
private int myfun()
{
int a = 100; //any number
int b = 0;
try
{
a = (5 / b);
return a;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return a;
}
// Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected"
finally
{
Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above
}
Response.Write("Statement after return after finally"); // -->Unreachable code
}
finally
, un péché:
try {
// do something risky
} catch (Exception ex) {
// handle an exception
} finally {
// do any required cleanup
}
est une opportunité garantie d'exécuter du code après votre try..catch
blocage, que votre bloc try ait lancé ou non une exception.
Cela le rend parfait pour des choses comme la libération de ressources, les connexions de base de données, les descripteurs de fichiers, etc.
Je vais expliquer l'utilisation de finalement avec une exception de lecteur de fichiers Exemple
try{ StreamReader strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); StreamReader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); }
dans l'exemple ci-dessus, si le fichier appelé Data.txt est manquant, une exception sera lancée et sera traitée mais l' instruction appelée StreamReader.Close();
ne sera jamais exécutée.
En raison de cela, les ressources associées au lecteur n'ont jamais été publiées.
StreamReader strReader = null; try{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); } catch (Exception ex){ Console.WriteLine(ex.Message); } finally{ if (strReader != null){ StreamReader.Close(); } }
Bon codage :)
Remarque: "@" est utilisé pour créer une chaîne textuelle , pour éviter l'erreur de "Séquence d'échappement non reconnue". Le symbole @ signifie lire cette chaîne littéralement et n'interpréter les caractères de contrôle autrement.
Supposons que vous deviez redéfinir le curseur sur le pointeur par défaut au lieu d'un curseur d'attente (sablier). Si une exception est levée avant de définir le curseur et ne plante pas carrément l'application, vous pourriez vous retrouver avec un curseur déroutant.
Parfois, vous ne voulez pas gérer une exception (pas de bloc catch), mais vous voulez que du code de nettoyage s'exécute.
Par exemple:
try
{
// exception (or not)
}
finally
{
// clean up always
}
Le bloc finally est précieux pour nettoyer toutes les ressources allouées dans le bloc try ainsi que pour exécuter tout code qui doit s'exécuter même s'il y a une exception. Le contrôle est toujours passé au bloc finally quelle que soit la façon dont le bloc try se termine.
Ahh ... je crois que je vois ce que tu dis! M'a pris une seconde ... vous vous demandez "pourquoi le placer dans le bloc finally au lieu après le bloc finally et complètement en dehors du try-catch-finally".
Par exemple, cela peut être dû au fait que vous arrêtez l'exécution si vous générez une erreur, mais que vous souhaitez toujours nettoyer les ressources, telles que les fichiers ouverts, les connexions à la base de données, etc.
Le flux de contrôle du bloc Final est soit après le bloc Try ou Catch.
[1. First Code]
[2. Try]
[3. Catch]
[4. Finally]
[5. After Code]
avec Exception 1> 2> 3> 4> 5 si 3 a une instruction Return 1> 2> 3> 4
sans exception 1> 2> 4> 5 si 2 a une instruction de retour 1> 2> 4
Comme mentionné dans la documentation :
Une utilisation courante de catch and finally est d'obtenir et d'utiliser des ressources dans un bloc try, de gérer des circonstances exceptionnelles dans un bloc catch et de libérer les ressources du bloc finally.
Cela vaut également la peine de lire ceci , qui déclare:
Une fois qu'une clause catch correspondante est trouvée, le système se prépare à transférer le contrôle vers la première instruction de la clause catch. Avant que l'exécution de la clause catch ne commence, le système exécute d'abord, dans l'ordre, toutes les clauses finally associées à des instructions try plus imbriquées que celle qui a intercepté l'exception.
Il est donc clair que le code qui réside dans une finally
clause sera exécuté même si une catch
clause antérieure avait une return
instruction.