En règle générale, oui, le enfin s'exécute.
Pour les trois scénarios suivants, le enfin fonctionnera TOUJOURS :
- Aucune exception ne se produit
- Exceptions synchrones (exceptions qui se produisent dans le flux de programme normal).
Cela inclut les exceptions conformes CLS qui dérivent de System.Exception et les exceptions non conformes CLS, qui ne dérivent pas de System.Exception. Les exceptions non conformes à CLS sont automatiquement encapsulées par RuntimeWrappedException. C # ne peut pas lever d'exceptions de réclamation non CLS, mais les langages tels que C ++ le peuvent. C # pourrait appeler du code écrit dans un langage qui peut lever des exceptions non conformes CLS.
- ThreadAbortException asynchrone À
partir de .NET 2.0, une ThreadAbortException n'empêchera plus finalement un de s'exécuter. ThreadAbortException est maintenant hissé avant ou après le finalement. Le finalement s'exécutera toujours et ne sera pas interrompu par un abandon de thread, tant que l'essai a été réellement entré avant que l'abandon du thread ne se produise.
Le scénario suivant, enfin, ne s'exécutera pas:
StackOverflowException asynchrone.
À partir de .NET 2.0, un débordement de pile entraînera la fin du processus. Le finally ne sera pas exécuté, à moins qu'une autre contrainte ne soit appliquée pour faire enfin du CER une région d'exécution contrainte. Les CER ne doivent pas être utilisés dans le code utilisateur général. Ils ne doivent être utilisés que s'il est essentiel que le code de nettoyage s'exécute toujours - une fois que tout le processus s'est arrêté en cas de débordement de pile et que tous les objets gérés seront donc nettoyés par défaut. Ainsi, le seul endroit où une CER devrait être pertinente est pour les ressources qui sont allouées en dehors du processus, par exemple, les descripteurs non gérés.
En règle générale, le code non managé est encapsulé par une classe gérée avant d'être consommé par le code utilisateur. La classe wrapper managé utilise généralement un SafeHandle pour encapsuler le handle non managé. SafeHandle implémente un finaliseur critique et une méthode Release exécutée dans une CER pour garantir l'exécution du code de nettoyage. Pour cette raison, vous ne devriez pas voir les URCE jonchées de code utilisateur complet.
Ainsi, le fait que finalement ne s'exécute pas sur StackOverflowException ne devrait pas avoir d'effet sur le code utilisateur, car le processus se terminera de toute façon. Si vous avez un cas limite où vous devez nettoyer une ressource non managée, en dehors d'un SafeHandle ou CriticalFinalizerObject, utilisez un CER comme suit; mais veuillez noter qu'il s'agit d'une mauvaise pratique - le concept non managé doit être abstrait pour une ou plusieurs classes gérées et des SafeHandle appropriés par conception.
par exemple,
// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This is *NOT* a CER
}
finally
{
// This is a CER; guaranteed to run, if the try was entered,
// even if a StackOverflowException occurs.
}