Ne Stream.Disposer toujours d'appel de Flux.De près (et de Flux.Flush)
Si j'ai la situation suivante:
StreamWriter MySW = null;
try
{
Stream MyStream = new FileStream("asdf.txt");
MySW = new StreamWriter(MyStream);
MySW.Write("blah");
}
finally
{
if (MySW != null)
{
MySW.Flush();
MySW.Close();
MySW.Dispose();
}
}
Pouvez je viens de l'appeler MySW.Dispose()
et de sauter la clôture, même si c'est prévu? Il n'existe aucun Flux implimentations qui ne fonctionnent pas comme prévu (Comme CryptoStream)?
Si non, alors est la suivante tout simplement mauvais code:
using (StreamWriter MySW = new StreamWriter(MyStream))
{
MySW.Write("Blah");
}
- pourquoi êtes-vous en profitant de vos variables locales? Ça fait mal à ma pauvre tête 🙁
- La convention où je suis est d'utiliser capitalisés locale étendue, et plus faible pour les params ( NewOrderLineItem vs newOrderLineItem). Juste ce que je suis habitué =)
- double possible de Fermer et Jetez - qui appeler?
- l'autre question est plus générique, et couvre de nombreux cas différents.
SqlConnection
présente quelques différences entreClose
etDispose
, quiStream
n'a pas.
Vous devez vous connecter pour publier un commentaire.
Oui, c'est ce qu'il est.
Il est sûr de supposer que si un objet implémente
IDisposable
, il va disposer de lui-même correctement.Si elle ne le fait pas, alors c'est un bug.
Non, ce code est la meilleure façon de traiter avec des objets qui implémentent
IDisposable
.Plus excellente de l'information est dans la accepté de répondre à Fermer et Jetez - qui appeler?
J'ai utilisé un Réflecteur et a constaté que
System.IO.Stream.Dispose
ressemble à ceci:Comme Daniel Bruckner mentionné, de Céder et de Proximité sont effectivement la même chose.
Cependant Flux n'est PAS d'appeler la méthode Flush() lorsqu'il est disposé/fermé. FileStream (et je suppose que n'importe quel Flux avec un mécanisme de mise en cache) ne appeler la méthode Flush() lors de son élimination.
Si vous êtes l'extension de Flux, ou MemoryStream etc. vous devrez mettre en place un appel à la méthode Flush() en cas de cession/fermé si c'est nécessaire.
Les Deux StreamWriter.Dispose() et de Flux.Dispose() libérer toutes les ressources détenues par les objets. Deux d'entre eux de fermer le flux sous-jacent.
Le code source du cours d'eau.Dispose() (à noter que c'est la mise en œuvre de détails, alors ne comptez pas sur elle):
StreamWriter.Dispose() (comme avec Stream.Dispose()):
Encore, j'ai l'habitude implicitement à proximité des ruisseaux/streamwriters avant de les jeter - je pense que c'est plus propre.
Tous les Flux standard (FileStream, CryptoStream) va tenter de chasse lors de la fermeture/cédées. Je pense que vous pouvez compter sur cela pour tout Microsoft flux implémentations.
Ainsi, Près/Jetez peut lever une exception si la chasse échoue.
En fait, autant que je me souvienne, il y avait un bug dans le .NET 1.0 mise en œuvre de FileStream dans la mesure où elle ne parviennent pas à libérer le handle de fichier si la chasse déclenche une exception. Ceci a été corrigé dans .NET 1.1, en y ajoutant un try/finally bloc pour l'Éliminer(boolean) méthode.
Pour les objets qui doivent être manuellement fermé, tous les efforts devraient être faits pour créer l'objet en utilisant le bloc.
De cette façon, on ne peut jamais tort d'accès "stream", hors du contexte de l'utilisation de la clause et le fichier est toujours fermé.
J'ai regardé dans le .net source du Ruisseau de la classe, il avait de la suite qui pourrait laisser penser que oui, vous pouvez...
Stream.Close
est mis en œuvre par un appel àStream.Dispose
ou vice-versa, de sorte que les méthodes sont équivalentes.Stream.Close
n'existe qu'en raison de la fermeture d'un flux de sons de plus naturel que de se débarrasser d'un ruisseau.En outre, vous devriez essayer d'éviter des appels explicites à ces méthodes et à l'utilisation de la
using
instruction afin d'obtenir la correcte gestion des exceptions pour gratuit.