tipos pattern net destructors crear constructores clases c# .net static destructor finalizer

c# - pattern - Finalizador estático



disposable c# pattern (5)

¿Cuál es la forma correcta de realizar una finalización estática?

No hay destructor estático. El evento AppDomain.DomainUnload no se genera en el dominio predeterminado. El evento AppDomain.ProcessExit comparte el tiempo total de los tres segundos (configuración predeterminada) entre todos los controladores de eventos, por lo que no es realmente utilizable.


Básicamente, no puedes. Diseña tu camino a su alrededor en la mayor medida posible.

No olvide que un programa siempre puede terminar abruptamente de todos modos, alguien sacando el poder es el ejemplo obvio. Entonces, cualquier cosa que hagas tiene que ser el "mejor esfuerzo", en cuyo caso, espero que AppDomain.ProcessExit sea ​​lo suficientemente bueno.

¿Qué necesitas hacer en tu caso particular?


Dos soluciones que me vienen a la mente:

  • No use una clase estática. Si utilizas una clase no estática e instancias, no tienes que preocuparte tanto por la limpieza.
  • Si eso no es una opción, argumentaría que esta es una buena situación para usar un singleton. Esto creará una instancia de una copia de su objeto y le pedirá que lo haga al finalizador, pero aún así le permitirá tratarlo como una clase estática en su mayor parte. Después de todo, su clase ya está estática y, por lo tanto, comparte la mayoría de las razones comunes para no utilizar un singleton.

Preguntaría qué estás cargando en tus métodos estáticos que necesitan ser lanzados. Ciertamente, no recomendaría hacer estas cosas en un método estático.

Dicho esto, su método estático podría instanciar un objeto que tiene un método de finalización.


Herfried Wagner ha escrito un excelente artículo explicando cómo implementar esto, por desgracia, en alemán (y VB). Aún así, el código debe ser comprensible.

Lo he intentado:

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"); } }

Parece funcionar exactamente de la misma manera que el evento AppDomain.ProcessExit : el finalizador obtiene ca. tres segundos ...


Para portar la respuesta de Michael Damatov (C #) que se basa en Herfried K. Wagner. (VB.NET) aquí está la versión 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!"); }

PS Al igual que el método AppDomain.ProcessExit, este no se puede llamar si el proceso finaliza anormalmente (desde el Administrador de tareas, por ejemplo). Otra advertencia es que si MyClass es genérico (con plantilla), la suposición de que su constructor estático y su destructor estático no se invocarán más de una vez por ejecución de la aplicación ya no será válida.