Share via


CA2202: No usar Dispose varias veces en objetos

Elemento Valor
RuleId CA2202
Category Microsoft.Usage
Cambio importante Poco problemático

Causa

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

Nota

Esta regla está en desuso. Para más información, consulte Reglas en desuso.

Descripción de la regla

Se puede llamar varias veces a un método Dispose implementado correctamente sin generar una excepción. Pero esto no está garantizado y, para evitar generar una excepción System.ObjectDisposedException, no debe llamar a Dispose más de una vez en un objeto.

Cómo corregir infracciones

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

Cuándo suprimir las advertencias

No suprima las advertencias de esta regla. Incluso si se sabe que Dispose del objeto se puede llamar varias veces de forma segura, la implementación podría cambiar en el futuro.

Ejemplo 1

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

En el ejemplo siguiente, se libera un objeto Stream que se crea en una instrucción using externa 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 using externa, el objeto stream se lanza 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...
    }
}

Ejemplo 2

Para resolver este problema, use un bloque try/finally en lugar de la instrucción using externa. En el bloque finally, asegúrese de que el recurso stream no sea 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
{
    stream?.Dispose();
}

Sugerencia

La sintaxis ?. anterior es el operador condicional null.

Consulte también