Conditions lorsque finalement ne s’exécute pas dans un .net try..finally block

StackOverflow https://stackoverflow.com/questions/111597

  •  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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top