.net - practice - vba try catch




Quel est le but du bloc finalement? (10)

Syntaxe de côté, quelle est la différence entre

try {
}
catch() {
}
finally {
    x = 3;
}

et

try {
}
catch() {
}

x = 3;

edit: dans .NET 2.0?

alors

try {
    throw something maybe
    x = 3
}
catch (...) {
    x = 3
}

est comportementalement équivalent?


@iAn et @mats:

Je ne "supprimerais" rien dans définitivement {} qui était "mis en place" dans le try {} en règle générale. Serait préférable de tirer la création de flux en dehors de l'essai {}. Si vous devez gérer une exception lors de la création de flux, cela peut se faire dans une plus grande mesure.

StreamReader stream = new StreamReader("foo.bar");  
try {
    mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally {
    stream.close();  
}

Cela dépend du langage car il peut y avoir de légères différences sémantiques, mais l'idée est qu'il s'exécutera (presque) toujours, même si le code dans le bloc try a créé une exception.

Dans le deuxième exemple, si le code dans le bloc catch retourne ou quitte, le x = 3 ne sera pas exécuté. Dans le premier ce sera.

Dans la plate-forme .NET, dans certains cas, l'exécution du bloc finally ne se produira pas: exceptions de sécurité, suspensions de threads, arrêt de l'ordinateur :), etc.


Eh bien, pour une chose, si vous retournez dans votre bloc try, le final sera toujours exécuté, mais pas le code listé sous le bloc try-catch-finally.


En Java, vous l'utilisez pour tout ce que vous voulez exécuter, que vous ayez utilisé un "return", que vous ayez simplement exécuté le bloc try ou qu'une exception ait été interceptée.

Par exemple, fermer une session de base de données ou une connexion JMS ou libérer une ressource du système d'exploitation.

Je suppose que c'est similaire dans .NET?


Enfin, les blocs vous permettent, en tant que développeur, de ranger vous-même, quelles que soient les actions du code précédent dans les erreurs du bloc try {}, et que d’autres aient signalé cela, sont principalement sous le parapluie de la libération des ressources - fermeture pointeurs / sockets / résultats, retour des connexions à un pool, etc.

@mats a tout à fait raison de dire qu'il y a toujours un risque d'échec "dur" - enfin, les blocs ne doivent pas inclure de code critique, ce qui devrait toujours être transactionnel dans try {}

@mats encore une fois - La vraie beauté est que cela vous permet de renvoyer des exceptions de vos propres méthodes, tout en vous garantissant:

try
{
StreamReader stream = new StreamReader("foo.bar");
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally
{
stream.close();
}

Ainsi, nous pouvons intercepter de nombreux types d'exceptions, les traiter différemment (le premier permet l'exécution de tout ce qui est au-delà de try {}, le second retourne effectivement), mais toujours clairement et proprement.


Le bloc finally a la même portée que try / catch, vous aurez donc accès à toutes les variables définies à l'intérieur.

Imaginez que vous ayez un gestionnaire de fichiers, c'est la différence dans la façon dont il serait écrit.

try
{
   StreamReader stream = new StreamReader("foo.bar");
   stream.write("foo");
}
catch(Exception e) { } // ignore for now
finally
{
   stream.close();
}

par rapport à

StreamReader stream = null;
try
{
    stream = new StreamReader("foo.bar");
    stream.write("foo");
} catch(Exception e) {} // ignore

if (stream != null)
    stream.close();

Rappelez-vous cependant que tout ce qui se trouve à l’intérieur n’est pas garanti. Imaginez que vous obtenez un signal d'abandon, Windows se bloque ou le pouvoir est parti. S'appuyer enfin sur le code critique de l'entreprise est mauvais.


Le bloc finally sera toujours appelé (enfin pas always ...) même si une exception est levée ou si une déclaration de retour est atteinte (bien que cela puisse dépendre de la langue). C'est un moyen de nettoyer que vous savez toujours appelé.


Plusieurs éléments rendent un bloc finalement utile:

  1. Si vous revenez des blocs try ou catch, le bloc finally est toujours exécuté, juste avant que le contrôle ne soit redonné à la fonction appelante
  2. Si une exception se produit dans le bloc catch ou qu'un type d'exception non capturé se produit dans le bloc try, le code du bloc finally est toujours exécuté.

Celles-ci rendent finalement les blocs excellents pour la fermeture des descripteurs de fichiers ou des sockets.


Vous pouvez donc nettoyer toutes les connexions ouvertes, etc. initialisées dans le bloc try. Si vous avez ouvert une connexion et qu'une exception s'est produite, cette exception ne serait pas correctement fermée. Ce type de scénario correspond à la définition du bloc finally.


try catch finalement est une construction assez importante. Vous pouvez être sûr que même si une exception est levée, le code in finalement bloc sera exécuté. Il est très important de gérer les ressources externes pour les libérer. La collecte des ordures ne le fera pas pour vous. En définitive, vous ne devriez pas avoir des déclarations de retour ou des exceptions. Il est possible de le faire, mais c'est une mauvaise pratique et peut conduire à des résultats imprévisibles.

Si vous essayez cet exemple:

try {
  return 0;
} finally {
  return 2;
}

Le résultat sera 2 :)

Comparaison avec d'autres langues: Return From Finally





try-catch-finally