à l'aide de déclaration FileStream et / ou StreamReader - Visual Studio 2012 Avertissements
Le nouveau Visual Studio 2012 est plaint d'une commune de la combinaison de code j'ai toujours utilisé. Je sais que cela semble exagéré, mais j'ai fait ce qui suit dans mon code "juste pour être sûr".
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var sr = new StreamReader(fs))
{
//Code here
}
}
Visual studio est un "avertissement" moi, je suis l'élimination de fs plus d'une fois. Donc ma question est-ce, serait la bonne façon d'écrire cet être:
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var sr = new StreamReader(fs);
//do stuff here
}
Ou devrais-je le faire de cette manière (ou d'une autre variante non mentionné).
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (var sr = new StreamReader(fs))
{
//Code here
}
J'ai cherché sur plusieurs questions dans StackOverflow mais n'a pas trouvé quelque chose qui a abordé la meilleure pratique pour cette combinaison directement.
Merci!
- +1: Bonne question, JUbbard80! 🙂
- Avec un double à l'aide de ce genre dans VS2013, un
FileStream
et unStreamReader
, il n'y a pas d'avertissement émis. Est-ce dû à la combinaison deFileStream
etStreamReader
? Ou ne VS2013 (par opposition à VS2012) reconnaître que cette double élimination est un nonissue?
Vous devez vous connecter pour publier un commentaire.
Les suivants est comment Microsoft recommande de le faire. Il est long et volumineux, mais en toute sécurité:
Cette méthode va toujours s'assurer que tout est disposé, qui devrait être en dépit de ce que des exceptions peuvent être jetés. Par exemple, si le
StreamReader
constructeur lève une exception, leFileStream
serait toujours bien disposé.Vous êtes, mais c'est très bien. La documentation pour IDisposable.Disposer lit:
Sur cette base, l'avertissement est faux, et mon choix serait de laisser le code tel qu'il est, et de supprimer l'avertissement.
Comme Dan la seule réponse qui ne semble travailler avec StreamWriter, je crois que ce pourrait être la réponse acceptable.
(Dan réponse sera toujours donner le cédé deux fois en garde StreamReader - Daniel Hilgarth et exacerbatedexpert mentionne, StreamReader dispose la filestream)
Ceci est très similaire à Daniel Hilgarth réponse, modifié pour appeler dispose via l'Utilisation de la déclaration sur le StreamReader comme il est maintenant clair StreamReader va appeler dispose sur FileStream (Selon tous les autres postes, la documentation de référence)
Mise à jour:
J'ai trouvé ce post. Pour ce qu'il vaut.
Ne l'élimination streamreader fermer le flux de données?
using (f(x)) { }
déclaration est vraiment compilé commey = f(x); using(y) { }
. Donc, toute exception levée par l'initialiseur de lausing
instruction de ne pas déclencher l'implicitefinally
déclaration. La meilleure façon de contourner ce problème est de concevoir des constructeurs à l'exception de sécurité et de propreté-ressources après un lancer, qui, je crois, leStream
classes.StreamReader
classe, je pense que le ci-dessus est tout à fait bien, mais si vous utilisiez une autre classe autre queStreamReader
, ou qu'ils changent la mise en œuvre dans le futur tel qu'il est possible que le constructeur lance une exception après l'intérieureIDisposable
dépendance a été instancié, puis l'intérieurIDisposable
ne seraient pas disposés. J'ai encore le droit de vote à l'exemple que j'ai posté est le plus sûr.Oui, la bonne façon serait d'utiliser votre première alternative:
La raison est la suivante:
L'élimination de la
StreamReader
ne dispose que de laFileStream
donc, c'est en fait la seule chose que vous devez éliminer.Votre deuxième option (juste à l'intérieur "à l'aide") n'est pas une solution car elle permettrait de quitter le
FileStream
undisposed si il y a une exception dans le constructeur de laStreamReader
.C'est parce que la façon dont vous avez utilisé
StreamReader
dispose le ruisseau quand il est éliminé. Donc, si vous mettez le flux de trop, c'est être disposé à deux reprises. Certains considèrent cela comme une faille dansStreamReader
- mais c'est qu'il ya aucun-le-moins. Dans VS 2012 (.NET 4.5) il y a une option dansStreamReader
de ne pas disposer de la rivière, avec un nouveau constructeur: http://msdn.microsoft.com/en-us/library/gg712952StreamReader
d'aller au-delà de sa responsabilité. Il provient probablement de la mentalité de toujours disposerIDisposable
ressources, mais la valeur par défaut dans ce cas devrait être le contraire, et l'option étendue devrait être de jeter si demandé.MemoryStream
objet. Très probablement, vous NE voulez PAS qu'elle a disposé de la même après qu'il est lu. Surtout utilisé dans les tests unitaires, mais il n'prouver un point.Deux solutions:
Un) en qui Vous avez confiance Réflecteur ou de la Documentation et vous savez
*Reader
et*Writer
va fermer le sous-jacent*Stream
. Mais attention: il ne fonctionne pas en cas de levée d'une Exception. Ce n'est pas la méthode recommandée:B) Vous ignorez l'avertissement que de la documentation états
The object must not throw an exception if its Dispose method is called multiple times.
C'est la méthode recommandée, car il est à la fois une bonne pratique de toujours utiliserusing
, et la sécurité en cas de levée d'une Exception:Compte tenu de toutes les absurdités de cette (parfaitement légitime!) question généré, ce serait ma préférence:
Les liens ci-dessous illustrent parfaitement légal de la syntaxe. OMI, cette "aide" de la syntaxe est de loin préférable à imbriquée "à l'aide". Mais je l'avoue -, il ne pas résoudre la question d'origine:
http://blogs.msdn.com/b/ericgu/archive/2004/08/05/209267.aspx
.NET - Remplacement imbriquée à l'aide des états avec la seule aide de déclaration
À mon humble avis...