11
votes

Stream.dispose ou flux = null?

J'ai du code similaire à celui-ci:

HttpWebRequest req;
HttpWebResponse response;
Stream receiveStream = null;
StreamReader readStream = null;
try
{
    req = (HttpWebRequest)WebRequest.Create("someUrl"));
    req.Credentials = CredentialCache.DefaultCredentials;

    req.Method = "GET";

    response = (HttpWebResponse)req.GetResponse();
    receiveStream = response.GetResponseStream();
    readStream = new StreamReader(receiveStream, Encoding.Default);

    return readStream.ReadToEnd();
}
catch
{
    return "Error";
}
finally 
{
    readStream = null;
    receiveStream = null;
    response = null;
    req = null;
}


3 commentaires

+1 Heureux que vous posiez cette question! La plupart des coques de copie et collé ignorent ceci.


Note latérale, mais cela peut ne pas être pertinent. Vous ne devriez pas avoir un attraper tout bloc. Ce n'est pas une bonne pratique. Vous voudriez rechercher, attraper et manipuler des exceptions spécifiques. Sinon, vous voulez que l'exception se propage. Si vous le savez déjà, pardonnez-moi.


Merci pour toutes les réponses. Je vais commencer à disposer :-) Pour le dossier, j'ai coupé la manipulation de l'exception de l'exemple de sorte que ce n'est pas aussi mauvais qu'elle apparaît bien que des commentaires, je pense que c'est autre chose qui peut être améliorée. Merci encore tout


11 Réponses :


27
votes

Il devrait avoir en utilisant [quels appels disposez () ].


0 commentaires

2
votes

Non, vous devriez appeler Disposer ou fermer


0 commentaires

1
votes

Oui - vous devez explicitement appeler () sur les classes qui implémentent Idisposable après que vous les avez utilisées - cela garantit que toutes leurs ressources sont nettoyées en temps opportun. Emballage de la variable dans un en utilisant () code> fait la même chose (qui ajoute du code d'emballage qui appelle pour vous):

using (StreamReader reader = new StreamReader()) {
    // do stuff with reader
}


0 commentaires

4
votes

Oui.

Lorsque vous vous êtes réglé sur NULL, il n'envoie que la référence. Il n'exécute aucun code de nettoyage que le créateur de la classe de flux a écrit.

Vous pouvez également vouloir considérer l'instruction à l'aide de () {} qui gère ceci pour vous sur des types isisposables.

Exemple: < Pré> xxx


0 commentaires

8
votes

Oui. À peu près tout ce qui implémente une méthode Dispose () doit avoir sa méthode d'élimination () appelée. Vous pouvez implicirement l'appeler dans A avec l'instruction "Utilisation":

using(StreamReader stream = GetStream())
{
   stream.DoStuff();
}


1 commentaires

Vous manquez le nom de la variable là-bas



28
votes

C'est presque toujours une erreur de définir des variables locales à NULL, à moins que vous ne souhaitiez utiliser cette valeur plus tard. Il ne forte pas la collecte des ordures plus tôt - si vous n'allez pas lire à partir de la variable plus tard, le collecteur des ordures peut ignorer la référence (lorsqu'il n'est pas en mode de débogage).

Cependant, il est presque toujours correct de fermer les flux - Idéalement dans un en utilisant la déclaration code> pour la simplicité. P>

C'est aussi em> presque toujours mal à avoir un bloc "attraper" nu comme ça. Voulez-vous vraiment gérer tout ce qui ne va pas em> vous tromper, y compris des choses comme OutofMemoryException code>? P>

Je refrécrirais votre code comme: p>

HttpWebRequest req = (HttpWebRequest) WebRequest.Create("someUrl"));
req.Credentials = CredentialCache.DefaultCredentials;
req.Method = "GET";

using (WebResponse response = req.GetResponse())
{
    using (StreamReader reader = new StreamReader(response.GetResponseStream(),
                                                  Encoding.Default))
    {
        return reader.ReadToEnd();
    }
}


1 commentaires

Il y a un avantage pour définir des variables locales à NULL: elle alerte les autres développeurs qu'ils doivent examiner très soigneusement le code de cette personne.



9
votes

oui, jetez-les ()

encore mieux de faire quelque chose comme xxx

A en utilisant (x) {} bloquer être réécrit (par le compilateur)
comme un essayer {} enfin {x.dispose ();}

Notez que le WebRequest n'est pas identifié.

Notez également que les lignes suivantes accomplissent la même chose que tout votre code: xxx


0 commentaires

0
votes

Il y a quelques gotchas dans les bibliothèques .NET. Le flux est un, et l'autre est une grande partie de l'API d'imagerie. Ces entités qui utilisent certaines ressources système ne couvrent pas les ressources système jointes.

Si quelque chose utilise l'API Idisposable, la meilleure chose à faire est de l'envelopper dans un bloc d'utilisation, car les gens l'ont souligné ci-dessus.

Lisez sur "Utilisation" et gardez-le à l'esprit chaque fois que vous traitez avec des poignées de fichier ou des images.


0 commentaires

0
votes

Vraiment, la question a été répondue mais je veux élaborer une chose.

à tout moment, un objet implémente l'interface Idisposable , vous devez le disposer avec la méthode de disposer ou (encore mieux) Utilisez le à l'aide de .

Si vous êtes jamais confronté à cette question à l'avenir, découvrez simplement quelles interfaces il met en œuvre. Une fois que vous avez vu Idisposable , vous savez le disposer.


0 commentaires

2
votes

Méthode la plus sûre:

try {
    HttpWebRequest request = (HttpWebRequest) WebRequest.Create("someUrl");
    request.Credentials = CredentialCache.DefaultCredentials;
    request.Method = "GET";
    using (HttpWebResponse response = (HttpWebResponse) request.GetResponse()) {
        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default)) {
            return reader.ReadToEnd();
        }
    }
} catch {
    return "Error";
}


0 commentaires

0
votes

Si vous avez besoin d'effacer l'utilisation du flux NULL; Sinon, utilisez le dispositif d'élimination (); PROCÉDÉ Si votre demande ne nécessite plus l'utilisation du flux.


1 commentaires

Qu'est-ce que "effacer le flux" signifie et que définit une référence variable à NULL a à voir avec elle?