2010-05-15 18 views
5

In C# è possibile creare riferimenti deboli agli oggetti come qui descritto:Riferimenti deboli e oggetti monouso

WeakReference Class

NET alcune classi anche implementare l'interfaccia IDisposable. La chiamata al metodo Dispose di questa interfaccia viene eseguita per smaltire manualmente tutte le risorse gestite o non gestite attualmente trattenute. Un esempio potrebbe essere un oggetto o una classe Bitmap.

Se assegno un oggetto che implementa IDisposable a un riferimento debole, verrà chiamato Dispose se il riferimento debole raccoglie l'oggetto?

+2

Che cosa si intende per "WeakReference" raccogliere i suoi oggetti? è solo un riferimento debole, cioè l'oggetto a cui punta può essere raccolto dal garbage collector. In questo caso, tutto ciò che sai del garbage collector si applica ... – flq

+0

Come Frank ha detto che l'oggetto sarà raccolto dal garbage collector. Questo a sua volta attiverà il finalizzatore, se ne hai uno. Tuttavia, il metodo Dispose non verrà mai attivato. – Steffen

risposta

5

In generale, la risposta è davvero No.

Tuttavia, una classe correttamente attuato che implementa IDisposable utilizzando i IDisposable pattern (hopefuly tutte le classi .NET fanno questo). Implementerebbe anche il finalizzatore che viene chiamato quando l'oggetto è garbage collection e all'interno del finalizzatore, chiamerebbe Dispose. Pertanto, per tutte le implementazioni corrette di IDisposable, verrà chiamato il metodo Dispose.

(Nota: il contro-esempio di Fernando non attua IDisposable correttamente)

+2

In realtà, il finalizzatore "standard" chiama solo 'Dispose (bool)'; 'Dispose()' non viene chiamato, quindi non è possibile eseguire alcuna pulitura che dipende dal codice gestito (ad es. Lo svuotamento dei flussi di file sottostanti). –

2

No. Semplice così;)

5

GC non chiama mai Dispose. Smaltire deve essere chiamato per codice utente.

+1

È possibile migliorare la progettazione sostituendo 'WeakReference' con' RefCountDisposable' dalla [libreria Rx] (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx). –

1

No. Controllare questo test:

class Program { 
     static void Main(string[] args) { 
      Test test = new Test(); 
      Console.WriteLine(test.Disposable == null); 
      GC.Collect(); 
      Console.WriteLine(test.Disposable == null); 
      Console.ReadLine(); 
     } 
    } 

    public class Test { 
     private WeakReference disposable = new WeakReference(new WeakDisposable()); 
     public WeakDisposable Disposable { 
      get { return disposable.Target as WeakDisposable; } 
     } 
    } 

    public class WeakDisposable : IDisposable { 
     ~WeakDisposable() { 
      Console.WriteLine("Destructor"); 
     } 
     public void Dispose() { 
      Console.WriteLine("Dispose"); 
     } 
    } 

L'output è:

False 
True 
Destructor 

Come si può vedere, l'esecuzione non colpisce il metodo Dispose.

Problemi correlati