Y a-t-il des situations où il convient d'utiliser un try-finally
bloc sans bloc catch
?
Vous l'utiliseriez pour vous assurer que certaines actions se produisent après le contenu 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 se propage dans la pile des appels.
Vous l'utiliseriez également par inadvertance lorsque vous utilisez le mot clé using
, car il se compile en try-finally
(pas une conversion exacte, mais pour les besoins de l'argument, elle est assez proche).
try
{
TrySomeCodeThatMightException();
}
finally
{
CleanupEvenOnFailure();
}
Le code exécuté dans finally
n'est pas garanti de fonctionner, cependant le cas où il n'est pas garanti est assez Edge - je ne m'en souviens même pas. Tout ce dont je me souviens, c'est que si vous êtes dans ce cas, il y a de fortes chances que ne pas exécuter le finally
ne soit pas votre plus gros problème :-) alors ne le transpirez pas.
Mise à jour depuis Tobias: finally
ne fonctionnera pas si le processus est tué.
Mise à jour de Paddy: Conditions quand finalement ne s'exécute pas dans un bloc .net try..finally
L'exemple le plus courant que vous pouvez voir est la suppression d'une connexion à une base de données ou d'une ressource externe même si le code échoue:
using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
// Do stuff.
}
Compile en quelque chose comme:
SqlConnection conn;
try
{
conn = new SqlConnection("");
// Do stuff.
}
finally
{
if (conn != null)
conn.Dispose();
}
using
est équivalent try-finally
. Vous n'utiliserez que try-finally
lorsque vous voulez faire un peu de nettoyage à l'intérieur finally
et ne vous souciez pas de l'exception.
meilleure approche sera
try
{
using(resource)
{
//Do something here
}
}catch(Exception)
{
//Handle Error
}
Faire même si le nettoyage appelé par using
échoue, votre code n'échouera pas.
Il existe certaines conditions lorsque finally
ne sera pas exécuté.
StackOverflowException
ou ExecutingEngineException
.J'espère que cela répond à votre doute.
Si vous disposez, par exemple, d'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 de libérer 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) est vraiment:
System.Threading.Monitor.Enter(x);
try { ... }
finally
{
System.Threading.Monitor.Exit(x);
}
Le bloc enfin sera toujours appelé pour s'assurer que le verrou exclusif est libéré.
Bonne explication en utilisant le code:
void MyMethod1()
{
try
{
MyMethod2();
MyMethod3();
}
catch(Exception e)
{
//do something with the exception
}
}
void MyMethod2()
{
try
{
//perform actions that need cleaning up
}
finally
{
//clean up
}
}
void MyMethod3()
{
//do something
}
Si MyMethod2 ou MyMethod3 lève une exception, elle sera interceptée par MyMethod1. Cependant, le code dans MyMethod2 doit exécuter du code de nettoyage, par exemple fermeture d'une connexion à une base de données, avant que l'exception ne soit transmise à MyMethod1.
Voici une situation où vous voudrez peut-être utiliser try finalement: lorsque vous utiliseriez normalement une instruction using, mais ne le pouvez pas parce que vous appelez une méthode par réflexion.
Cela ne fonctionnera pas
using (objMsg = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO")))
{
}
utilisez plutôt
object objMsg = null;
try
{
objMsg
= Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO"));
strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public
| BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg,
new object[] { vxmlRequest.OuterXml });
}
finally
{
if (objMsg!=null)
((IDisposable)objMsg).Dispose();
}
Vous avez besoin d'un bloc finally, quand peu importe quelles exceptions (le cas échéant) sont interceptées ou même si aucune n'est interceptée, vous voulez toujours exécuter du code avant la fin du bloc. Par exemple, vous souhaiterez peut-être fermer un fichier ouvert.
Voir aussi try-finally
essayez/enfin: lorsque vous ne voulez pas gérer d'exceptions mais que vous voulez vous assurer que certaines actions se produisent, qu'une exception soit levée ou non par le code appelé.
Jetez un œil sur le lien suivant: https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause
Cela dépend de l'architecture de votre application et de l'opération que vous effectuez dans le bloc.
Voici un cas d'utilisation que j'utilise toujours (euh ..):
int? x; //note the nullable type here!
try
{
x = int.Parse(someString);
}
catch { } //don't care, let it just be null
Je ne sais rien de C #, mais il semble que tout ce que vous pourriez faire avec un essai, enfin, vous pourriez le faire plus élégamment avec un en utilisant l'instruction . C++ n'a même pas de finalement comme n résultat de son RAII .
1. nous pouvons utiliser le bloc try sans catch mais nous devons utiliser le catch/enfin, n'importe lequel d'entre eux. 2.Nous ne pouvons pas utiliser uniquement le bloc try.