Conditions lorsque finalement ne s’exécute pas dans un .net try..finally block
-
02-07-2019 - |
Question
En gros, j’ai entendu dire que certaines conditions feraient sauter .net au-delà du dernier bloc. Est-ce que quelqu'un sait quelles sont ces conditions?
La solution
Deux possibilités:
Le bloc finally ne sera pas exécuté s'il existe une exception StackOverflowException
car il n'y a plus de place dans la pile pour exécuter du code supplémentaire. Il ne sera également pas appelé lorsqu’il y aura une ExecutionEngineException
, susceptible de résulter d’un appel à Environment.FailFast ()
.
Autres conseils
Sauf si le CLR explose et tombe en panne avec une exception ExecutingEngineException (j'en ai vu quelques-uns dans les jours .net 1.1 avec juste ce qu'il fallait de COM Interop :) .. Je pense que finalement, toujours exécuter.
Vous pouvez obtenir une situation où le code dans le bloc try provoque une exception SecurityException avant le bloc try entré (l’exception est levée lors de l’appel de la méthode conteneur (voir http://msdn.microsoft.com/en-us/library/fk6t46tz (VS.71) .aspx )), dans cette situation, vous ne saisissez jamais le bloc try, le code du bloc finally n'est jamais appelé.
Les autres possibilités incluent StackOverflowException et ExecutingEngineException.
Enfin, le bloc
sur le thread d'arrière-plan
peut ne pas s'exécuter. Cependant, cela dépend de l'exécution terminée du thread de premier plan principal
qui termine l'opération de thread d'arrière-plan
avant même l'exécution complète du thread d'arrière-plan
.
class Program
{
static void Main(string[] args)
{
Program prgm = new Program();
Thread backgroundThread = new Thread(prgm.CheckBgThread);
backgroundThread.IsBackground = true;
backgroundThread.Start();
Console.WriteLine("Closing the program....");
}
void CheckBgThread()
{
try
{
Console.WriteLine("Doing some work...");
Thread.Sleep(500);
}
finally
{
Console.WriteLine("This should be always executed");
}
}
}
Il existe également une méthode Application.Exit.
Ni le code qui suit un bloc finally, ni le code des portées externes, ne s'exécutera sans que le bloc finally ait été démarré en premier (une exception dans le bloc finally peut le faire quitter prématurément, auquel cas l'exécution sortirait du finaliseur à une portée externe). Si du code antérieur au bloc finally se bloque dans une boucle sans fin ou une méthode qui ne se ferme jamais, ou si le contexte d'exécution est complètement détruit, le bloc finally ne s'exécutera pas.
Notez qu'il convient de faire appel à des blocs, contrairement à "Finalize". méthodes (ou "destructeurs" C #) qui ne doivent pas être utilisées correctement.