2010-05-15 10 views
5

En C# es posible crear referencias débiles a objetos tal como se describe aquí:referencias débiles y objetos desechables

WeakReference Class

En algunas clases de .NET también implementar la interfaz IDisposable. La llamada al método Dispose de esta interfaz se realiza para deshacerse manualmente de los recursos administrados o no administrados que se están reteniendo actualmente. Un ejemplo podría ser un objeto o clase de mapa de bits.

Si asigno un objeto que implementa IDisposable a una referencia débil, ¿se invocará Dispose si la referencia débil recoge el objeto?

+2

¿Qué quiere decir con "WeakReference", recogiendo sus objetos? es solo una referencia débil, es decir, el objeto al que apunta puede ser recolectado por el recolector de basura. En este caso, todo lo que usted sabe sobre el recolector de basura se aplica ... – flq

+0

Como Frank dijo, el recolector de basura solo recogerá el objeto. Esto a su vez activará el finalizador, si tiene uno. El método Dispose nunca se activará. – Steffen

Respuesta

5

En general, la respuesta es, en efecto Nº

Sin embargo, una clase implementa correctamente que implementa IDisposable utilizando los IDisposable pattern (hopefuly todas las clases .NET hacer esto). También implementaría el finalizador que se llama cuando el objeto es basura recolectada y dentro del finalizador, llamaría al Dispose. Por lo tanto, para todas las implementaciones adecuadas de IDisposable, se llamará al método Dispose.

(Nota: el contraejemplo de Fernando no está cumpliendo adecuadamente IDisposable)

+2

En realidad, el finalizador "estándar" solo llama a 'Dispose (bool)'; 'Dispose()' no se llama, por lo que no se puede realizar ninguna limpieza que dependa del código administrado (por ejemplo, el vaciado de flujos de archivos subyacentes). –

5

GC nunca llama a Dispose. Dispose debe llamarse por código de usuario.

+1

Su diseño puede ser mejor servido reemplazando 'WeakReference' con' RefCountDisposable' de la [Biblioteca de Rx] (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx). –

1

No. de esta prueba:

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"); 
     } 
    } 

La salida es:

False 
True 
Destructor 

Como se puede ver, la ejecución no golpea el método Dispose.

Cuestiones relacionadas