2012-08-25 10 views
22

Ho una classe con membri statici estesi, alcuni dei quali mantengono riferimenti a oggetti gestiti e non gestiti.Come e quando vengono eliminati i membri statici C#?

Ad esempio, il costruttore statico viene chiamato non appena viene fatto riferimento al tipo, il che fa sì che la mia classe ruoti su un bloccoQueue di attività. Questo succede quando viene chiamato uno dei metodi statici, per esempio.

Ho implementato IDisposable, che mi dà i metodi per gestire lo smaltimento su qualsiasi oggetto di istanza che ho creato. Tuttavia, questi metodi non vengono mai chiamati se il consumatore non crea oggetti di istanza dalla mia classe.

Come e dove inserire il codice per disporre dei riferimenti gestiti dalla parte statica della mia classe? Ho sempre pensato che lo smaltimento delle risorse a riferimenti statici si verificava quando veniva rilasciato l'ultimo oggetto istanza; questa è la prima volta che ho creato una classe in cui nessuna istanza potrebbe mai essere creata.

+1

articoli statiche sono disponibili per l'intera esecuzione dell'applicazione. Non si creano oggetti statici usando la NUOVA parola chiave, quindi questo significa che non si hanno più istanze di nulla, perché in realtà non si istanzia nulla. Riguardo agli oggetti gestiti, non preoccuparti di loro, il GC si prenderà cura di loro. Le risorse non gestite tentano di utilizzarle in una classe non statica oppure verranno conservate fino alla chiusura dell'applicazione. Gli articoli statici non supportano lo smaltimento. – alexandrudicu

+0

Grazie. Sembra che ho bisogno di riconsiderare il mio design qui. – Joe

risposta

35

Le variabili statiche della classe non vengono raccolte automaticamente finché il dominio dell'app che ospita la classe non viene scaricato. Il metodo Dispose() non verrà chiamato, perché è un metodo di istanza e hai detto che non avresti creato alcuna istanza della tua classe.

Se si desidera utilizzare il metodo Dispose(), rendere un oggetto singleton, creare una sua istanza e disporne esplicitamente quando l'applicazione sta per uscire.

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

Questo ha senso. Sospettavo che forse avrei dovuto usare un singleton a caso su questo ... grazie per il tuo aiuto. – Joe

0

È necessario smaltire manualmente questi oggetti, non è possibile creare un "finalizzatore" per le risorse statiche.

+1

Come posso eliminarli manualmente? Come mi verrà notificato che ho bisogno di fare questo? – Joe

+0

@Joe Dipende solo da te. Solo tu sai quando è il momento di chiamare Dispose di qualcosa che è staticamente tenuto. – vcsjones

+0

Ad esempio, si veda l'esempio nella domanda originale, in cui io faccio ruotare un blocco di azioni. Questa coda dovrebbe essere eseguita fino a quando l'utente non desidera più rilasciare Azioni (tramite metodo statico). Lasciatemi rendere più chiaro; quando uccido l'attività che prosciuga quella coda? Quindi, quando lo uccido? Come faccio a sapere che la mia classe non è più "portata" per l'utente? – 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 
    } 
} 
Problemi correlati