2012-04-11 4 views
5

Por ejemplo tengo un métodoAutodisposing objetos

SomeMethod(Graphics g) 
{ 
    ... 
} 

Si voy a llamar a este método de manera

SomeMethod(new Graphics()) 

se opondrá ser autodisposed mis gráficos o debería llamar g.Dispose() manualmente en el final de ¿el método?

SomeMethod(Graphics g) 
{ 
    ... 
    g.Dispose(); 
} 
+4

Además de 'no', su método tampoco * debe * ser responsable de eliminar el objeto gráfico. Es importante que la vida útil de los objetos gráficos se administre en un solo lugar, lo que significa que debe desecharse en la misma clase que la creó. Tener un objeto en un lugar indeterminado en la pila de llamadas hace que el código sea difícil de entender y mantener, y podría llevar a errores más adelante. – MattDavey

Respuesta

7

objetos desechables no conseguirán autodisposed (lo más cerca que puede llegar a que está implementando un finalizador que llama Dispose si es necesario). Debe hacerlo manualmente llamando al Dispose() o utilizándolo con un bloque using.

Si desea automática disponer el objeto, usted puede hacer esto:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

El uso de bloques asegura que el método Dispose() se llama automáticamente tan pronto como los extremos de bloque (por lo que en este caso, después SomeMethod devuelve o arroja una excepción).

Nota: si es posible, debe desechar el objeto en la ubicación cercana a donde lo creó. Tomar un objeto válido y eliminarlo dentro del método podría causar confusión.

Los gráficos y probablemente la mayoría si no todas las clases BCL que implementan esta interfaz también llamarán al Dispose() cuando se llame al Finalizer. Esto es parte de una implementación adecuada de IDisposable. Sin embargo, nunca se sabe cuándo se llama al finalizador y no debe confiar en este detalle de implementación si necesita que su objeto se elimine de manera determinista.

+1

En mi ejemplo anterior, ¿el objeto gráfico se autodispondrá o no? –

+0

No. Ver mi edición. – Botz3000

+0

Espera, ¿estás diciendo que el GC no llamará a 'Dispose' cuando el objeto esté finalizado? (Dada una implementación correcta de 'IDisposable') – leppie

3

probablemente debería utilizar una instrucción using

using (var graphicsObject = new Graphics()) { 
    SomeMethod(graphicsObject); 
} 

El objeto será automáticamente colocado en el extremo de la instrucción using, incluso si se produce una excepción.

2

Comprobar Graphics Class

public sealed class Graphics : MarshalByRefObject, 
    IDeviceContext, IDisposable 

Implementa la interfaz IDisposable, por lo que si se utiliza la instrucción using con el objeto Graphics entonces será dispuesto de forma automática.

En su ejemplo

SomeMethod(Graphics g) 
     { 
     ... 
     g.Dispose(); 
     } 

será eliminada sin usar el g.Dispose, pero la mejor práctica es using comunicado.

ejemplo:

using (Graphics g = this.CreateGraphics()) 
{ 
//Do some graphics operation. 
} 
4

La forma correcta de trabajar con objetos desechables es envolverlos en using bloques:

using (var g = new Graphics()) { 
    SomeMethod(g); 
} 

Cuando la ejecución deja el bloque using la Graphics se desechan correctamente, incluso si una se arroja una excepción

Sin embargo, si no se deshaga el objeto, ya sea de forma explícita o implícitamente el uso de un bloque using el objeto seguirá recibiendo dispuesta cuando es basura recogida (suponiendo que el finalizador llama correctamente el Dispose como debería). Cuando eso ocurra no está bajo su control y es por eso que debe asegurarse de que los objetos desechables se desechen adecuadamente tan pronto como ya no sean necesarios para liberar los recursos reclamados por los objetos.

2

En su ejemplo, no debe disponer de un objeto como argumento. Esto no es aconsejable porque ese objeto podría usarse fuera de su método. La eliminación de objetos de utilidad debe (normalmente) tener lugar en el mismo método que usted lo crea. Excepción para objetos de clase amplia u objetos de estado.

Como en otras respuestas, use using para crear y eliminar un objeto. Esto solo es realmente necesario en objetos que usan algunos recursos valiosos, como la conexión a una base de datos. Una vez dicho esto, siempre debe llamar al Dispose() (explícitamente o por using) si el objeto lo implementa porque eso significa que utiliza grandes cantidades de recursos no administrados.

Todos los objetos de .NET Framework que no llame a Dispose en (de cualquier manera) finalmente se autodispondrán por Garbage Collector. La implementación adecuada de la interfaz IDisposable debe tener un destructor/finalizador que llame al Dispose. Esto es para asegurarse de que no se pierdan recursos valiosos solo por un código incorrecto. Sus recursos se liberarían mucho más tarde, pero lo harían y eso es importante. Así es como se implementan todas las clases desechables en .NET y cómo todas las clases deberían implementar IDisposable.

El código debería tener este aspecto:

using(Graphics g = new Graphics()) 
{ 
    SomeMethod(g) 
    { 
     ... 
    } 
} 

Comprobar this de las recomendaciones de Microsoft sobre IDisposable.Dispose método.

Cuestiones relacionadas