Condividi tramite


CA2202: Non eliminare oggetti più volte

Articolo Valore
ID regola CA2202
Category Microsoft.Usage
Modifica Nessuna interruzione

Causa

Un'implementazione del metodo contiene percorsi di codice che potrebbero causare più chiamate a System.IDisposable.Dispose o un equivalente Dispose, ad esempio un metodo Close() su alcuni tipi, nello stesso oggetto.

Nota

Questa regola è stata deprecata. Per altre informazioni, vedere Regole deprecate.

Descrizione regola

Un metodo implementato Dispose correttamente può essere chiamato più volte senza generare un'eccezione. Tuttavia, questo non è garantito e per evitare di generare un System.ObjectDisposedException oggetto non è consigliabile chiamare Dispose più volte su un oggetto.

Come correggere le violazioni

Per correggere una violazione di questa regola, modificare l'implementazione in modo che, indipendentemente dal percorso del codice, Dispose venga chiamata una sola volta per l'oggetto.

Quando eliminare gli avvisi

Non escludere un avviso da questa regola. Anche se Dispose per l'oggetto è noto che è possibile chiamare più volte in modo sicuro, l'implementazione potrebbe cambiare in futuro.

Esempio 1

Le istruzioni annidate using (Using in Visual Basic) possono causare violazioni dell'avviso CA2202. Se la risorsa IDisposable dell'istruzione interna using annidata contiene la risorsa dell'istruzione esterna using , il Dispose metodo della risorsa nidificata rilascia la risorsa contenuta. Quando si verifica questa situazione, il Dispose metodo dell'istruzione esterna using tenta di eliminare la risorsa per una seconda volta.

Nell'esempio seguente un Stream oggetto creato in un'istruzione using esterna viene rilasciato alla fine dell'istruzione inner using nel metodo Dispose dell'oggetto che contiene l'oggetto StreamWriterstream . Alla fine dell'istruzione esterna using , l'oggetto stream viene rilasciato una seconda volta. La seconda versione è una violazione di CA2202.

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

Esempio 2

Per risolvere questo problema, usare un try/finally blocco anziché l'istruzione esterna using . finally Nel blocco assicurarsi che la stream risorsa non sia 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();
}

Suggerimento

La ?. sintassi precedente è l'operatore condizionale Null.

Vedi anche