Freigeben über


CA2202: Objekte nicht mehrmals verwerfen

TypeName

DoNotDisposeObjectsMultipleTimes

CheckId

CA2202

Kategorie

Microsoft.Usage

Unterbrechende Änderung

Nicht unterbrechend

Ursache

Eine Methodenimplementierung enthält Codepfade, die möglicherweise mehrere Aufrufe von IDisposable.Dispose oder einer Entsprechung von Dispose, z. B. einer Close()-Methode für bestimmte Typen, für dasselbe Objekt verursachen.

Regelbeschreibung

Eine ordnungsgemäß implementierte Dispose-Methode kann mehrmals aufgerufen werden, ohne dass eine Ausnahme ausgelöst wird. Da dies jedoch nicht gewährleistet ist, sollten Sie Dispose nicht mehr als einmal für ein Objekt aufrufen, um zu vermeiden, dass System.ObjectDisposedException generiert wird.

Verwandte Regeln

CA2000: Objekte verwerfen, bevor Bereich verloren geht

Behandeln von Verstößen

Um einen Verstoß gegen diese Regel zu beheben, ändern Sie die Implementierung so, dass Dispose unabhängig vom Codepfad nur einmal für das Objekt aufgerufen wird.

Wann sollten Warnungen unterdrückt werden?

Unterdrücken Sie keine Warnung dieser Regel. Auch wenn bekannt ist, dass Dispose für das Objekt gefahrlos mehrfach aufgerufen werden kann, ist es möglich, dass die Implementierung sich zu einem späteren Zeitpunkt ändert.

Beispiel

Geschachtelte using-Anweisungen (Using in Visual Basic) können Verletzungen der CA2202-Warnung verursachen. Wenn die IDisposable-Ressource der geschachtelten inneren using-Anweisung die Ressource der äußeren using-Anweisung enthält, gibt die Dispose-Methode der geschachtelten Ressource die enthaltene Ressource frei. Wenn diese Situation auftritt, versucht die Dispose-Methode der äußeren using-Anweisung, ihre Ressource zu einem zweiten Mal freizugeben.

Im folgenden Beispiel wird ein Stream-Objekt, das in einer äußeren using-Anweisung erstellt wurde, am Ende der inneren using-Anweisung in der Dispose-Methode des StreamWriter-Objekts freigegeben, das das stream-Objekt enthält. Am Ende der äußeren using-Anweisung wird das stream-Objekt ein zweites Mal freigegeben. Die zweite Freigabe ist eine Verletzung von CA2202.

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

Um dieses Problem zu beheben, verwenden Sie einen try/finally-Block statt der äußeren using-Anweisung. Stellen Sie im finally-Block sicher, dass die stream-Ressource nicht NULL ist.

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();
}

Siehe auch

Referenz

System.IDisposable

Implementieren der Methoden "Finalize" und "Dispose" zum Bereinigen von nicht verwalteten Ressourcen