Compartir a través de


CA2202: No aplicar Dispose a los objetos varias veces

Nombre de tipo

DoNotDisposeObjectsMultipleTimes

Identificador de comprobación

CA2202

Categoría

Microsoft.Usage

Cambio problemático

No

Motivo

Una implementación de un método contiene rutas de acceso del código que podrían provocar varias llamadas a IDisposable.Dispose o a un equivalente de Dispose, como un método Close() en algunos tipos, en el mismo objeto.

Descripción de la regla

Se puede llamar varias veces a un método Dispose implementado correctamente sin iniciar una excepción.Sin embargo, no está garantizado; en consecuencia, para evitar que se genere una excepción System.ObjectDisposedException, no se debe llamar a Dispose más de una vez en un objeto.

Reglas relacionadas

CA2000: Eliminar objetos antes de perder el ámbito

Cómo corregir infracciones

Para corregir una infracción de esta regla, cambie la implementación de modo que únicamente se llame a Dispose una vez para el objeto, independientemente de la ruta de acceso del código.

Cuándo suprimir advertencias

No suprima las advertencias de esta regla.Aunque sepa que Dispose es invocable varias veces para el objeto con seguridad, la implementación podría cambiar en el futuro.

Ejemplo

Las instrucciones using anidadas (Using en Visual Basic) pueden producir infracciones de la advertencia CA2202.Si el recurso IDisposable de la instrucción using interna anidada contiene el recurso de la instrucción using exterior, el método Dispose del recurso anidado libera el recurso contenido.Cuando esta situación se produce, el método Dispose de la instrucción using exterior intenta disponer de su recurso durante una segunda vez.

En el ejemplo siguiente, un objeto Stream que se crea en una instrucción using externa se libera al final de la instrucción using interna en el método Dispose del objeto StreamWriter que contiene el objeto stream.Al final de la instrucción exterior using, el objeto de stream se libera una segunda vez.La segunda versión es una infracción de CA2202.

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        // Use the writer object...
    }
}

Para resolver este problema, use el bloque try/finally en lugar de la instrucción using exterior.En el bloque finally, asegúrese de que el recurso stream no es NULL.

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    if(stream != null)
        stream.Dispose();
}

Vea también

Referencia

System.IDisposable

Implementing Finalize and Dispose