2010-03-12 16 views
29

¿Cuál es la mejor práctica para cuándo implementar IDisposable?¿Cuándo debería implementar IDisposable?

¿Es la mejor regla empírica implementarlo si tiene un objeto gestionado en la clase, o depende si el objeto se creó en la clase o acaba de pasar? ¿Debo hacerlo también para las clases sin objetos administrados?

+2

@Earwicker: Si has encontrado más que yo sobre ese tema, te agradecería que me lo compartieras. – Bobby

+2

http://stackoverflow.com/search?q=IDisposable+owner –

Respuesta

26

Si se refiere a objetos no administrados, entonces sí, debe implementarlo cada vez que tenga uno o más recursos no administrados que esté manejando en su clase. También debe utilizar el patrón cuando posiblemente se aferre a objetos que pueden ser identificados por sí mismos, y asegúrese de desecharlos cuando se deshaga de su clase.

(de acuerdo en que esta cuestión ya se ha pedido a las veces suficientes como para ejecutar una pequeña impresora sin tinta en caso de que se impriman ...)

6

Debe implementar IDisposable cuando su clase contiene recursos que desea liberar cuando haya terminado de usarlos.

0

Si tiene propiedades que también deben eliminarse.

6

Cuando su clase contiene objetos no administrados, recursos, archivos abiertos u objetos de bases de datos , debe implementar IDisposable.

4

Creo que the docs son bastante claros acerca de para qué IDisposable es bueno.

El uso principal de esta interfaz es para liberar recursos no administrados. El recolector de basura automáticamente libera la memoria asignada a un objeto administrado cuando ese objeto no es más usado. Sin embargo, no es posible predecir cuando se producirá la recolección de basura . Además, el recolector de elementos no utilizados no tiene conocimiento de de recursos no administrados como los identificadores de ventana , o abre archivos y secuencias.

Incluso tiene un ejemplo. En ese ejemplo, la clase que implementa IDisposable contiene un identificador. Se debe liberar un controlador cuando ya no se usa. Esto se hace en el método Dispose(). Entonces, el usuario de esa clase ve que implementa IDisposable y sabe que la clase debe eliminarse explícitamente cuando ya no sea necesaria (para que se pueda liberar el identificador). Es una buena práctica (es decir, una regla) que siempre deba llamar al Dispose() en instancias IDisosable cuando la instancia ya no es necesaria.

10

Si bien todos mencionaron recursos (no administrados), tengo otra cosa que agregar: la utilizo cuando necesito eliminar conexiones de controladores de eventos que de otra manera evitarían que una clase saliera del alcance y se recolectara basura.

Como ejemplo, tengo un servicio que se inyecta en una vista secundaria, esa vista secundaria se suscribirá a varios eventos de tipo asincrónico en el servicio. El propietario de esa vista secundaria no tiene idea de cuál es el tipo concreto, simplemente lo tiene como una interfaz. El servicio puede quedar fuera del alcance en algún momento arbitrario en el futuro, y no quiero que se quede sin GC. Al deshacerse de esa vista secundaria, el propietario llamará a Dispose sobre ella para darle la oportunidad de desenganchar cualquier manejador de eventos. Aquí hay un ejemplo ligeramente artificial (y muy pseudocódigo), observe cómo la interfaz para la vista secundaria también implementa IDisposable.

public class OwnerView { 

    public OwnerView() { 
     _childView = new ChildView(myServiceReference); 
    } 

    public void CloseChildView() { 
     if (childView != null) { 
      _childView.Close(); 
      _childView.Dispose(); 
     } 

     _childView = null; 
    } 

    private IChildView _childView; 
} 

public class ChildView : IChildView { 

    public ChildView(MyService serviceRef) { 
     _serviceRef = serviceRef; 
     _serviceRef.GetSettingsAsyncFinished += new EventHandler(someEventHandler); 
    } 

    public void IDisposable.Dispose() { 
     _serviceRef -= someEventHandler; 
    } 

    private MyService _serviceRef; 
} 

public interface IChildView : IDisposable { 
    void DoSomething(); 
    ... etc ... 
} 

Hay mucho más autorizada comentarios sobre este de los demás en SO, como Do event handlers stop garbage collection from occuring? y Garbage collection when using anonymous delegates for event handling. También puede consultar este artículo codeproject.

Cuestiones relacionadas