2010-06-10 17 views
6

¿Hay alguna manera de controlar cuándo se cierra una aplicación que está utilizando el dll? La DLL y la aplicación son ambas C#, tampoco son Windows Forms.Necesita saber cuándo se cierra la aplicación

Puedo verificar cuando la aplicación principal se está cerrando, pero me gustaría que el archivo DLL vea "hey, el programa se está cerrando y liberándome, debería hacerlo muy rápido antes de morir".

¿Alguna manera de hacerlo? ¿O estoy atascado con el plato de la aplicación "haz esto antes de morir"?

+1

¿Por qué lo necesitas? Las DLL administradas liberan sus recursos automáticamente por el recolector de basura. Si necesita liberar recursos no administrados, use Finalización. –

+0

@FractalizerR: El uso de finalizadores para liberar recursos es * no * recomendado porque es indeterminista. En cambio, el objeto debería implementar 'IDisposable'. –

Respuesta

8

¿Quizás el evento AppDomain.ProcessExit funcionaría para usted? Tenga en cuenta lo siguiente, aunque (a partir de los documentos):

El tiempo total de ejecución de todos los controladores de eventos ProcessExit es limitado, al igual que el tiempo total de ejecución de todos los finalizadores se limita al proceso de apagado. El valor predeterminado es dos segundos. Un host no administrado puede cambiar este tiempo de ejecución de llamando al ICLRPolicyManager::SetTimeout método con el valor enumeración OPR_ProcessExit.

+0

Gracias. Intenté implementarlo, sin embargo, no creo que se llame al evento. No estoy seguro si hay un truco para hacerlo funcionar. Lo hice AppDomain.CurrentDomain.ProcessExit + = new EventHandler (CurrentDomain_ProcessExit); y, por lo que puedo ver, no irá a CurrentDomain_ProcessExit. Mi forma de verificar es el código que quiero, y también mostrar un cuadro de mensaje de winform cuando llegue allí. El cuadro debe aparecer y luego desaparecer, o aparecer y luego colgar la aplicación del apagado normal. Pero ninguno de los dos sucede. :( – Nick

+0

@Nick: puede compartir los detalles de esa implementación (actualice la pregunta, por ejemplo). Lo probé como lo describe y funciona como esperaba. –

+0

Funcionó para mí (TM), luego en el segundo o ¡Tercer intento dejó de funcionar !? Estoy terminando mi proceso mediante la detección de Ctrl-C y la salida graciosa. – gatopeich

1

No conocemos los detalles de su código, pero el hecho de que la biblioteca de su clase tenga en cuenta cuándo se está produciendo el proceso podría indicar un error de diseño en su aplicación.

Si necesita liberar recursos o limpiar otras cosas de manera determinista, debería echar un vistazo a la interfaz IDisposable. Si las clases expuestas por su biblioteca implementan esta interfaz, la persona que llama puede decir fácilmente que ya no necesita la funcionalidad dll llamando al Dispose().

Tal vez un buen punto de partida para la lectura adicional son los siguientes artículos:

Por ejemplo, usted podría tener la siguiente clase en la biblioteca de clases:

using System; 
using System.IO; 

public class ResourceManager : IDisposable 
{ 
    private Stream _resource; 
    private bool _disposed; 

    public void Dispose() 
    { 
     Dispose(true); 

     // Use SupressFinalize in case a subclass 
     // of this type implements a finalizer. 
     GC.SuppressFinalize(this); 
    } 

    public void Dispose(bool disposing) 
    { 
     if (!_disposed) 
     { 
      if (disposing) 
      { 
       Console.WriteLine("Exiting Process. Cleaning up."); 
       // free resources here 
       if (_resource != null) 
        _resource.Dispose(); 
       Console.WriteLine("Object disposed."); 
      } 

      // Indicate that the instance has been disposed. 
      _resource = null; 
      _disposed = true; 
     } 
    } 
} 

En el módulo principal se puede utilizar de la siguiente manera; la declaración using garantizará que el método se llama Dispose():

using System; 
using System.Windows.Forms; 

static class Program 
{ 
    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     using (ResourceManager manager = new ResourceManager()) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 
} 
+0

Es un controlador de dispositivo y, como tal, necesita liberar el dispositivo y, de ser posible, volver a establecerlo en estado neutral cuando la aplicación usarlo se va y no hace su deber de limpieza. Por lo tanto, necesito que esté en la DLL. Cuando un programa usa el dll, puede que no se llame desechable, puede que se vaya. Lo usaré yo solo en mi programa, así como otros que podrían no tener la misma codificación. – Nick

+0

@Nick: liberar recursos no manipulados como su dispositivo es exactamente el escenario para usar g 'IDisposable()'. –

+0

Pero, si las personas no usan los productos desechables o los usan, ¿no se los llamará correctos? – Nick

0

AppDomain.ProcessExit "normalmente" el trabajo, pero no se guarateed para disparar si un proceso es terminado por el administrador de tareas, por ejemplo. Por lo tanto, puede que no sea ideal si el controlador de su dispositivo necesita liberar recursos grandes, etc. (es decir, es posible que no se liberen hasta que el GC se acerque a él).

Ver Rick Stahls blog para más detalles.

0

Si es la aplicación de consola, debe hacer como la respuesta aceptada en this question. Y es mejor desarrollar usando la interfaz IDisposable.

Cuestiones relacionadas