102 votes

CA2202, comment faire pour résoudre ce cas

Quelqu'un peut-il me dire comment supprimer tous les CA2202 avertissements à partir du code suivant?

public static byte[] Encrypt(string data, byte[] key, byte[] iv)
{
    using(MemoryStream memoryStream = new MemoryStream())
    {
        using (DESCryptoServiceProvider cryptograph = new DESCryptoServiceProvider())
        {
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptograph.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                using(StreamWriter streamWriter = new StreamWriter(cryptoStream))
                {
                    streamWriter.Write(data);
                }
            }
        }
        return memoryStream.ToArray();
    }
}

Avertissement 7 CA2202 : Microsoft.Utilisation : l'Objet "cryptoStream' peuvent être éliminés plus d'une fois dans la méthode 'CryptoServices.Chiffrer(string, byte[], byte[])'. Pour éviter de générer un Système.ObjectDisposedException vous ne devriez pas appeler dispose de plus d'une heure sur un objet.: Lignes: 34

Avertissement 8 CA2202 : Microsoft.Utilisation : l'Objet "memoryStream' peuvent être éliminés plus d'une fois dans la méthode 'CryptoServices.Chiffrer(string, byte[], byte[])'. Pour éviter de générer un Système.ObjectDisposedException vous ne devriez pas appeler dispose de plus d'une heure sur un objet.: Lignes: 34, 37

Vous avez besoin de Visual Studio Analyse du Code pour voir ces mises en garde (ce ne sont pas de compilateur c# mises en garde).

144voto

Jordão Points 29221

Vous devez supprimer les avertissements dans ce cas. Le code qui traite des produits jetables devrait être cohérent, et vous ne devriez pas savoir qu’autres classes s’approprient les jetables que vous avez créé :

40voto

Hans Passant Points 475940

Eh bien, il est précis, la méthode dispose() sur ces cours d'eau sera appelé plus d'une fois. La classe StreamReader prendra la "propriété" de la cryptoStream donc l'élimination streamWriter permettra également de disposer cryptoStream. De même, la classe CryptoStream en prend la responsabilité de la memoryStream.

Ce ne sont pas exactement les bugs réels, ces .NET les classes sont résistants à de multiples Dispose() appels. Mais si vous voulez vous débarrasser de l'avertissement alors vous devez supprimer l'instruction à l'aide de ces objets. Et la douleur vous-même un peu de raisonnement ce qui va se passer si le code génère une exception. Ou fermer le message d'avertissement avec un attribut. Ou tout simplement les ignorer l'avertissement, car il est stupide.

9voto

Joe Points 60749

Je voudrais faire cela à l'aide de #pragma warning disable.

L' .NET Framework lignes Directrices recommandent de mettre en œuvre IDisposable.Disposer d'une telle manière qu'elle peut être appelée plusieurs fois. À partir de MSDN description de IDisposable.Disposer:

L'objet ne doit pas lever une exception si sa méthode dispose est appelé plusieurs fois

Par conséquent, la mise en garde semble être presque dénuée de sens:

Pour éviter de générer un Système.ObjectDisposedException vous ne devriez pas appeler dispose de plus d'une heure sur un objet

Je suppose qu'il pourrait être soutenu que l'avertissement peut être utile si vous utilisez un mal mis en œuvre IDisposable objet qui ne respecte pas les normes de mise en œuvre des lignes directrices. Mais lors de l'utilisation de classes à partir de la .NET Framework comme vous le faites, je dirais qu'il est sûr de supprimer l'avertissement à l'aide d'un #pragma. Et à mon avis c'est préférable de passer à travers des cerceaux comme suggéré dans la documentation MSDN pour cet avertissement.

9voto

dtb Points 104373

Lorsqu'un StreamWriter est éliminé, il sera automatiquement disposer le enveloppés de Flux (ici: la CryptoStream). CryptoStream également automatiquement dispose le enveloppés de Flux (ici: la MemoryStream).

Si votre MemoryStream est disposé à la fois par la CryptoStream et l' aide de l'instruction. Et votre CryptoStream est éliminé par le StreamWriter et de l'extérieur à l'aide de l'instruction.


Après quelques essais, il semble être impossible de se débarrasser des avertissements. Theorectically, MemoryStream doit être éliminée, mais alors vous, théoriquement, ne pouvait pas accéder à sa méthode ToArray plus. Pratiquement, un MemoryStream n'a pas besoin d'être éliminés, alors j'aimerais aller avec cette solution et de supprimer la CA2000 avertissement.

var memoryStream = new MemoryStream();

using (var cryptograph = new DESCryptoServiceProvider())
using (var writer = new StreamWriter(new CryptoStream(memoryStream, ...)))
{
    writer.Write(data);
}

return memoryStream.ToArray();

1voto

Shiraz Bhaiji Points 34901

La classe cryptostream est issue d’un memorystream.

Ce qui semble se produire est que lorsque la crypostream est supprimée (à la fin de l’utilisation) memorystream est également supprimé, puis memorystream est disposé à nouveau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X