2010-03-25 12 views
15

¿Se llama a un destructor si la aplicación falla? Si se trata de una excepción no controlada, supongo que sí, pero ¿qué pasa con los errores más graves, o algo así como un usuario que mata el proceso de solicitud?Destructor: recibe un aviso si la aplicación falla

Y un par de preguntas más potencialmente mudos:

  • lo que ocurre con todos los objetos de una aplicación cuando han sido ejecutadas las salidas de aplicaciones y todos los finalizadores - hacen los objetos reciben basura recogida o son de alguna manera todos " descargado "con el proceso o dominio de aplicación?
  • es la parte del recolector de basura de cada aplicación (se ejecuta en el mismo proceso) o es independiente?
+1

¿Qué tipo de bloqueo? Las excepciones no son un bloqueo, sino errores recuperables. – Dykam

Respuesta

21

Te animo a probar esto por ti mismo. Por ejemplo:

using System; 

class Program { 
    static void Main(string[] args) { 
    var t = new Test(); 
    throw new Exception("kaboom"); 
    } 
} 
class Test { 
    ~Test() { Console.WriteLine("finalizer called"); } 
} 

Ejecutar esto en el símbolo del sistema para que pueda ver el último suspiro. Primero con la declaración de lanzamiento comentada.

Como cualquier excepción no controlada en Windows, el filtro de excepción predeterminado que proporciona Windows invoca el cuadro de diálogo Informes de errores de Windows, mostrado por WerFault.exe. Si hace clic en "Cerrar programa", WerFault usará TerminateProcess() para matar el programa. Eso es un final rápido, no hay oportunidad de ejecutar el hilo del finalizador, como sucedería cuando un programa sale normalmente.

Windows se encarga de la limpieza de la metralla. Cierra automáticamente los controles del sistema operativo que su programa pudo haber abierto pero no tuvo la oportunidad de cerrar en el finalizador. Los archivos son el problema más complicado aquí, sus búferes no se vacían y fácilmente terminará con un archivo parcialmente escrito en el disco.

+1

+1. Thx, muy informativo. Definitivamente voy a intentar esta y algunas otras ideas para ver qué está pasando. – anakic

4

Ni siquiera sé C#, pero en función de mis experiencias con otros lenguajes de programación, supongo: si una aplicación falla, eso significa que hay algo realmente malo en ella. Manejo de memoria incorrecto, etc. Sería extraño que cualquier lenguaje de programación intente ejecutar destructores/desasignadores/finalizadores/... en tal caso. Las cosas serían, probablemente, sólo tiene que ir más equivocado;)

Actualización: (se olvidó de tratar de responder a sus otras preguntas) de nuevo, no específico de C#, pero por lo general no hay garantía de que los destructores/deallocators/finalizadores/... en realidad ser llamado. La razón de esto es que cuando un proceso se cierra, es mucho más fácil y eficiente simplemente "zap" el bloque de memoria utilizado para el proceso que ejecutar sus destructores, etc. para limpiar la memoria.

No estoy seguro de cómo responder a su última pregunta sin entrar en demasiados detalles técnicos. Hay varias maneras en que los recolectores de basura pueden diseñarse y ejecutarse, la más fácil es que la recolección de basura detenga el proceso actual y lo continúe cuando esté terminado, aunque también es posible (aunque más difícil) tener recolectores de basura que se ejecuten simultáneamente. con procesos cuya memoria están recolectando.

Es posible que desee leer sobre la teoría de la recolección de basura para comprender mejor todo esto. De hecho, hay un sitio completo sobre este tema: www.memorymanagement.org.

+0

Thx, buena respuesta.Pero una cosa no parece correcta: dices que incluso si la aplicación sale normalmente, que algunos destructores aún no se llamarán ... No me parece correcto, ya que no hay forma de que el recolector de basura o nadie else (excepto los objetos mismos) para saber qué tipo de recursos nativos podrían haber usado los objetos administrados de la aplicación, por lo que no pueden manejar eso. De todos modos lo probaré, como nobugs sugeridos, y publicaré los resultados cuando tenga un poco de tiempo ... – anakic

+0

Realmente no puedo decir para C#, pero Objective-C proporciona un ejemplo interesante aquí. Debe comparar la documentación para 'dealloc' (que es el destructor cuando el GC está apagado) y 'finalizar' (cuando el GC está encendido). Para 'dealloc', los documentos dicen de manera muy explícita que no hay garantía de que se llame y no se debe confiar en él para, por ejemplo, cerrar un archivo. Para 'finalizar', los documentos son más confusos, parece sugerir que puede confiar en 'finalizar' como 'copia de seguridad' para asegurarse de que el archivo se cierre, etc., pero no puedo encontrar una oración que diga explícitamente 'finalizar' es garantizado para ser llamado. – Rinzwind

+0

Aquí hay un enlace a la documentación para 'dealloc' y 'finalize' en Objective-C. Por cierto: mientras que simplemente intenta un experimento para ver si estos se llaman en C# es bueno, también debe echar un vistazo a la documentación. Si su experimento muestra que recibe una llamada, pero los documentos no dicen que hay una * garantía *, esto puede cambiar en futuras versiones o en otras plataformas, por lo que es mejor que no confíe en ello. Obj-C doc. link: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc – Rinzwind

3

Si mata una aplicación, la aplicación casi perderá el control al 100% y no hay posibilidad de que llame al destructor.

Cuestiones relacionadas