CA2202 : Ne pas supprimer des objets plusieurs fois
TypeName |
DoNotDisposeObjectsMultipleTimes |
CheckId |
CA2202 |
Catégorie |
Microsoft.Usage |
Modification avec rupture |
Modification sans rupture |
Cause
Une implémentation de méthode contient des chemins d'accès de code qui peuvent provoquer des appels multiples à IDisposable.Dispose ou un équivalent Dispose (par exemple, une méthode Close() sur certains types sur le même objet).
Description de la règle
Une méthode Dispose correctement implémentée peut être appelée plusieurs fois sans lever d'exception.Toutefois, cela n'est pas garanti et pour éviter de générer System.ObjectDisposedException, vous ne devez pas appeler Dispose plusieurs fois sur un objet.
Règles connexes
CA2000 : Supprimez les objets avant d'être hors de portée
Comment corriger les violations
Pour corriger une violation de cette règle, modifiez l'implémentation afin que Dispose soit appelé une seule fois pour l'objet, quel que soit le chemin d'accès de code.
Quand supprimer les avertissements
Ne supprimez aucun avertissement de cette règle.Même si Dispose pour l'objet peut être appelé plusieurs fois sans risque, l'implémentation peut changer à l'avenir.
Exemple
Les instructions using imbriquées (Using en Visual Basic) peuvent provoquer des violations de l'avertissement CA2202.Si la ressource IDisposable de l'instruction using interne imbriquée contient la ressource de l'instruction using externe, la méthode Dispose de la ressource imbriquée libère la ressource contenue.Lorsque cette situation se produit, la méthode Dispose de l'instruction using externe essaie de supprimer sa ressource pour la deuxième fois.
Dans l'exemple suivant, un objet Stream créé dans une instruction using externe est libéré à la fin de l'instruction using interne dans la méthode Dispose de l'objet StreamWriter qui contient l'objet stream.À la fin de l'instruction using externe, l'objet de stream est diffusé une deuxième fois.La deuxième version finale est une violation de CA2202.
using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
using (StreamWriter writer = new StreamWriter(stream))
{
// Use the writer object...
}
}
Pour résoudre ce problème, utilisez un bloc try/finally au lieu de l'instruction using externe.Dans le bloc finally, assurez-vous que la ressource stream n'est pas 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();
}