2012-08-25 13 views
22

Tengo una clase con miembros estáticos extensos, algunos de los cuales mantienen referencias a objetos administrados y no administrados.¿Cómo y cuándo están dispuestos los miembros estáticos C#?

Por ejemplo, el constructor estático se invoca tan pronto como se hace referencia al Tipo, lo que hace que mi clase active una Cola de Tareas. Esto sucede cuando uno de los métodos estáticos se llama, por ejemplo.

Implementé IDisposable, que me da los métodos para manejar la eliminación en cualquier objeto de instancia que creé. Sin embargo, estos métodos nunca se invocan si el consumidor no crea ningún objeto de instancia de mi clase.

¿Cómo y dónde pongo el código para eliminar las referencias mantenidas por la parte estática de mi clase? Siempre pensé que la eliminación de los recursos de referencia estática se producía cuando se liberaba el último objeto de instancia; esta es la primera vez que alguna vez he creado una clase donde nunca se pueden crear instancias.

+1

elementos estáticos están disponibles para toda la ejecución de la aplicación. No crea elementos estáticos con la palabra clave NEW, por lo que no tiene varias instancias de nada, porque en realidad no instancia nada. Acerca de los objetos administrados, no se preocupe por ellos, el GC se encargará de ellos. Acerca de los recursos no administrados, intente utilizarlos en una clase no estática, o se guardarán hasta que cierre su aplicación. Los artículos estáticos no son compatibles con la eliminación. – alexandrudicu

+0

Gracias. Parece que necesito reconsiderar mi diseño aquí. – Joe

Respuesta

35

La variable estática de su clase no se recolecta hasta que se descarga el dominio de la aplicación que aloja su clase. No se llamará al método Dispose(), porque es un método de instancia, y usted dijo que no crearía ninguna instancia de su clase.

Si desea hacer uso del método Dispose(), haga que su objeto sea único, cree una instancia y deséchelo explícitamente cuando su aplicación esté a punto de salir.

public class MyClass : IDisposable { 
    public IList List1<int> {get; private set;} 
    public IDictionary<string,string> Dict1 {get; private set;} 
    public void Dispose() { 
     // Do something here 
    } 
    public static MyClass Instance {get; private set;} 
    static MyClass() { 
     Instance = new MyClass(); 
    } 
    public static void DisposeInstance() { 
     if (instance != null) { 
      Instance.Dispose(); 
      Instance = null; 
     } 
    } 
} 
+0

Eso tiene sentido. Sospeché que podría tener que usar un patrón Singleton eventualmente en esto ... gracias por su ayuda. – Joe

0

Debería deshacerse de estos objetos manualmente, no hay forma de crear un "finalizador" para los recursos estáticos.

+1

¿Cómo los desecharía manualmente? ¿Cómo me notificarán que necesito hacer esto? – Joe

+0

@Joe Eso depende enteramente de usted para decidir. Solo tú sabes cuándo es el momento de llamar Eliminar de algo estático. – vcsjones

+0

Por ejemplo, vea el ejemplo en la pregunta original, donde hago girar una Querta de acciones de bloqueo. Esta cola debe ejecutarse hasta que el usuario ya no quiera incluir Acciones en ella (a través del método estático). Déjeme aclarar eso; ¿Cuándo elimino la tarea que agota esa cola? Entonces, ¿cuándo lo mato? ¿Cómo sabré que mi clase ya no está en "alcance" para el usuario? – Joe

0
public class Logger : IDisposable 
{ 

    private string _logDirectory = null; 
    private static Logger _instance = null; 

    private Logger() : this(ConfigurationManager.AppSettings["LogDirectory"]) 
    { 
     AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; 
    } 

    private Logger(string logDirectory) 
    { 
    } 

    public static Logger Instance 
    { 
     get 
     { 
      if (_instance == null) 
       _instance = new Logger(); 
      return _instance; 
     } 
    } 

    private void CurrentDomain_ProcessExit(object sender, EventArgs e) 
    { 
     Dispose(); 
    } 



    public void Dispose() 
    { 
     // Dispose unmanaged resources 
    } 
} 
Cuestiones relacionadas