42 votes

Finaliseur statique

Quelle est la bonne façon d'effectuer une finalisation statique ?

Il n'y a pas de destructeur statique. Le site AppDomain.DomainUnload n'est pas déclenché dans le domaine par défaut. Le site AppDomain.ProcessExit partage le temps total des trois secondes (paramètres par défaut) entre tous les gestionnaires d'événements, il n'est donc pas vraiment utilisable.

45voto

Michael Damatov Points 5453

Herfried Wagner a écrit un excellent article expliquant comment implémenter ceci - hélas, en allemand (et VB). Néanmoins, le code devrait être compréhensible.

Je l'ai essayé :

static readonly Finalizer finalizer = new Finalizer();

sealed class Finalizer {
  ~Finalizer() {
    Thread.Sleep(1000);
    Console.WriteLine("one");
    Thread.Sleep(1000);
    Console.WriteLine("two");
    Thread.Sleep(1000);
    Console.WriteLine("three");
    Thread.Sleep(1000);
    Console.WriteLine("four");
    Thread.Sleep(1000);
    Console.WriteLine("five");
  }
}

Il semble fonctionner exactement de la même manière que le programme AppDomain.ProcessExit L'événement fait : le finisseur obtient environ trois secondes...

31voto

Jon Skeet Points 692016

En gros, vous ne pouvez pas. Contournez-le autant que possible.

N'oubliez pas qu'un programme peut toujours se terminent brusquement de toute façon - quelqu'un qui retire l'électricité étant l'exemple évident. Donc tout ce que vous faites doit être "le meilleur effort" - dans ce cas, je ferais certainement espoir que AppDomain.ProcessExit serait suffisant.

Que devez-vous faire, dans votre cas particulier ?

8voto

Jason Baker Points 56682

Deux solutions qui me viennent à l'esprit :

  • N'utilisez pas de classe statique. Si vous utilisez une classe non statique et l'instanciez, vous n'aurez pas à vous soucier autant du nettoyage.
  • Si ce n'est pas une option, je dirais que c'est une bonne situation pour utiliser un singleton. Cela instanciera une copie de votre objet et le finaliseur sera appelé à la sortie, mais vous pourrez toujours le traiter comme une classe statique pour la plupart. Après tout, votre classe est déjà statique et partage donc la plupart des raisons courantes de ne pas utiliser un singleton.

6voto

Ady Points 4132

Je me demande ce que vous chargez dans vos méthodes statiques qui doivent être libérées. Je ne recommanderais certainement pas de faire ces choses dans une méthode statique.

Cela dit, votre méthode statique pourrait instancier un objet qui possède une méthode finalise.

0voto

ILIA BROUDNO Points 16

Pour porter la réponse de Michael Damatov (C#) qui est basée sur Herfried K. Wagner. (VB.NET) voici la version C++/CLI :

ref class MyClass
{
        ref class StaticFinalizer sealed
        {
            !StaticFinalizer();
        };
        static initonly StaticFinalizer^ stDestr = gcnew StaticFinalizer();
}

MyClass::StaticFinalizer::!StaticFinalizer()
{
    System::Diagnostics::Debug::WriteLine("In StaticFinalizer!");
}

P.S. Tout comme la méthode AppDomain.ProcessExit, celle-ci ne peut pas être appelée si le processus se termine anormalement (depuis le Task Manager par exemple). Une autre mise en garde est que si MyClass est générique (templated), l'hypothèse selon laquelle son constructeur statique et son destructeur statique ne seront pas appelés plus d'une fois par exécution de l'application n'est plus valable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X