2008-11-25 13 views
23

Me gustaría saber cuándo debería y no debería estar envolviendo cosas en un bloque de USO.C# USING keyword: ¿cuándo y cuándo no usarla?

Por lo que entiendo, el compilador lo traduce en un try/finally, donde finalmente llama a Dispose() en el objeto.

Siempre utilizo una UTILIZACIÓN en torno a las conexiones de bases de datos y el acceso a archivos, pero es más por hábito que por comprensión al 100%. Sé que deberías explícitamente (o con un uso) Dispose() objetos que controlan los recursos, para garantizar que se liberen al instante en lugar de cuando el CLR lo parezca, pero ahí es donde se rompe mi comprensión.

¿No se eliminan los IDisposables cuando salen del alcance?

¿Solo necesito usar USING cuando mi objeto hace uso de Dispose para arreglarse?

Gracias

Editar: Sé que hay un par de otras funciones en la palabra clave usando, pero estoy más interesado en las respuestas relacionadas con el CLR y exactamente lo que está pasando en el interior

Andrew

Respuesta

21

No, IDisposable artículos no se eliminan cuando salen del alcance. Es precisamente por esta razón que necesitamos IDisposable - para una limpieza determinista.

eventualmente obtienen basura recolectada, y si hay un finalizador se llamará (tal vez) - pero eso podría ser un largo tiempo en el futuro (no es bueno para grupos de conexión, etc.). La recolección de basura depende de la presión de la memoria: si nada quiere memoria adicional, no hay necesidad de ejecutar un ciclo de GC.

Curiosamente (tal vez) hay algunos casos en los que "usar" es un dolor - cuando la clase ofensiva arroja una excepción en Dispose() a veces. WCF es un ofensor de esto. He discutido este tema (con una solución simple) here.

Básicamente - si la clase implementa IDisposable, y propia una instancia (es decir, que lo creó o lo que sea), es su trabajo para asegurarse de que se dispone. Eso podría significar a través de "usar", o podría significar pasarlo a otro código que asume la responsabilidad.

De hecho, he visto depurar el código del tipo: "¿Está IDisposables no desecharse cuando que salir de su ámbito"

#if DEBUG 
    ~Foo() { 
     // complain loudly that smoebody forgot to dispose... 
    } 
#endif 

(donde las llamadas DisposeGC.SuppressFinalize)

+0

Y si utiliza esta técnica, por favor, no olvide el '#if DEBUG'. Ese eres tú, estoy pensando en JetBrains, con tus 30000 objetos en la cola del finalizador de Visual Studio ... –

+2

Oh, eso es desafortunado. –

+0

+1, ojalá pudiera hacer más de 1 voto: p ... excelente conocimiento compartido en stackoverlow ... es genial ... –

5

No. Si el objeto es IDisposable finalizables, que no es lo mismo, entonces se finalizará cuando es basura recogida.

Que podría ser pronto o casi nunca.

El libro C#/CLR de Jeff Richter es muy bueno en todo esto, y el libro de pautas de diseño del marco también es útil.

qué sólo necesito utilizar una USANDO cuando mi objeto hace uso de botar a poner en orden a sí misma?

Puede única uso 'utilizar' cuando el objeto implementa IDisposable. El compilador objetará si intenta hacer lo contrario.

2

Para agregar a las otras respuestas, debe usar using (o un Dispose explícito) siempre que un objeto contenga recursos que no sean la memoria administrada. Los ejemplos serían cosas como archivos, sockets, conexiones de bases de datos o incluso identificadores de dibujo GDI.

El recolector de basura eventualmente finalizará estos objetos, pero solo en algún momento no especificado en el futuro. No puede confiar en que suceda de manera oportuna, y es posible que se haya quedado sin ese recurso mientras tanto.

+2

Podría decirse que simplemente debería usar "usar" cada vez que la clase implemente IDisposable. Lo que hace es un detalle de implementación ;-p Es un * finalizador * que solo debe agregar si su clase está envolviendo un recurso no administrado. Hay ejemplos de IDisposable en código puramente administrado ... –

+0

Buen comentario, debería haberlo convertido en una respuesta para votar love xx –

+0

Marc: tienes razón. Creo que realmente estaba tratando de explicar la motivación de por qué el implementador podría haber hecho una clase IDisposable, en lugar de la recolección de basura para resolver todos los problemas de administración de recursos. – babbageclunk

Cuestiones relacionadas