11
votes

Emballage MemoryStream dans une utilisation

On m'a dit que System.IO.MemoryStream n'a pas besoin d'être enveloppé dans un bloc en utilisant le bloc car il n'y a pas de ressource sous-jacente, ce genre de temps va à l'encontre de ce que j'ai toujours raconté des flux ( "En cas de doute, utilisez un en utilisant ").

est-ce vrai? Pourquoi alors fait exemple MSDN Utilisez-en un (résumé ci-dessous) ? xxx


2 commentaires

Pour crédit supplémentaire;) Quel est le terme (plus) correct. a) Envelopper dans un Utilisateur B) Intégrer dans une utilisation C) Utilisation dans une utilisation D) Mise en œuvre dans une utilisation E) Autre?


envelopper ou incorporer, utiliser ou mettre en œuvre ne sonne pas bien dans ce contexte


6 Réponses :


6
votes

Une ligne directrice est que si cela implémente Idisposable, vous devez en disposer. Vous travaillez simplement avec une API et ne sont pas au courant de la mise en œuvre, vous n'avez donc aucune raison de ne pas la mettre dans un bloc d'utilisation.


0 commentaires

3
votes

Vous ne perdez rien en enveloppant le flux de mémoire dans un bloc à l'aide d'un bloc, alors s'il y a du doute, faites-le simplement. :)


2 commentaires

Cela peut entraîner des problèmes avec les services WCF hébergés dans IIS ainsi que MVC. Mais je suggérerais d'utiliser "en utilisant", à moins que cela ne cause des problèmes.


Pourriez-vous élaborer ou fournir un pointeur à des informations sur les problèmes avec WCF / IIS et MVC?



4
votes

Si la classe implémente Idisposable, elle devrait être disposée.

Vous n'avez pas besoin de me donner la peine de deviner si cela fait quelque chose de signification ou non - c'est pour la classe de décider et de mettre en œuvre. Si la classe ne fait rien lorsque l'objet est éliminé, il n'y a vraiment aucun coût de toute façon, il n'y a donc aucun mal.

L'encapsulation est l'une des pierres angulaires du développement orienté objet. Pourquoi sortir de votre façon de casser cela, surtout s'il n'y a pas de bonne raison?


0 commentaires

5
votes

avoir eu un aspect rapide dans réflecteur , il apparaît que Disposez sur le MemoryReam Peu d'autre que pour marquer le flux comme n'étant pas ouvert, écrit ou extensible.

Ayant dit que, comme une approche générale, vous devriez probablement rester avec le modèle d'élimination; Evéniquement comme Stream S Suivez toutes l'approche "Decorator" et doit être facile à échanger les uns pour les autres, ou enroulez-en un avec un autre. MemodReam peut être échangé pour un autre flux qui se soucie de demain.


0 commentaires

3
votes

comme Charlie a déclaré , c'est une pratique recommandée de disposer de tous les objets de classes qui implémentent Idisposable.

Si vous examinez la mise en œuvre de MemoryStream.Dispose (BOOL) (qui est appelée par Stream.Dispose ()), il devient évident que vous devriez être éliminé de cela puisqu'il met à jour quelques drapeaux de contrôle: < Pré> xxx


5 commentaires

Ces drapeaux ne sont pas une bonne raison d'appeler en eux-mêmes. Si cela traçait une ressource, ce serait une bonne raison. Marquage du flux comme non écrite, lorsque nous avons fini de l'utiliser quand même vous achète absolument rien. Je conviens que comme un point de pratique que vous devriez, mais comme des spécificités de mémoire Morthstream, je suis en désaccord avec votre réponse.


Je ne suis pas d'accord avec votre déclaration de "marquage du flux comme non écrite, lorsque nous avons fini de l'utiliser quand même vous n'ayé absolument rien.". Une autre partie du code pourrait avoir une référence à la mémoire Morthstream et tenter d'y écrire une autre partie après votre disposition. Vous devez décider / vérifier si l'autre code devrait vraiment écrire sur la mémoire Morthstream. En fonction du résultat de l'analyse, vous modifiez le code qui ne doit pas écrire sur le Morthstream ou déplacer le dispositif d'éliminer ailleurs; Ou changez le code en tout sens dans votre scénario.


Accrochez-vous - l'OP demande s'il doit envelopper le flux dans une "utilisation". Cela implique que son scénario d'utilisation est tout dans une méthode, un autre code ne peut donc pas y avoir de référence. C'est mon point - dans ce cas, il vous achète rien. S'il s'agissait d'un flux de niveau de classe, c'est une question éventuellement différente, mais ce n'est pas dans ce cas d'utilisation.


Non, cela peut être une preuve solide, mais cela n'implique pas que son scénario d'utilisation est tout dans une méthode. "// Les choses" dans son échantillon est ouverte. Vous supposez qu'il ne transmet pas l'objet à une autre partie du code (membre d'un autre objet qui pourrait être déclaré hors de la portée de l'utilisation) qui pourrait contenir une référence de manière potentialité et essayer d'y écrire une fois que vous l'avez disposée.


"// Stufft" dans sa méthode est tout dans la déclaration à l'aide de l'utilisation, de sorte que cela n'aurait pas d'importance s'il l'a transmis comme un argument à une autre méthode. Quoi qu'il en soit, je n'essaie vraiment pas de vous appâter, et oui, il est possible de conjurer des scénarios d'utilisation où mon hypothèse tombe en panne. Je pense que nous ne sommes tout simplement pas d'accord sur la question de savoir si les rares drapeaux internes sont une raison convaincante d'appeler, esp. pour ce scénario d'utilisation.



30
votes

L'idiome C # est que si un objet implémente Idisposable , vous utilisez un à l'aide du bloc . Cela permettra à toutes les ressources utilisées par l'objet être éliminée correctement. Vous n'êtes pas supposé connaître les détails de la mise en œuvre du MemoryStream . Ce que vous savez, c'est que cela implémente Idisposable pour que vous puissiez disposer correctement. En outre, vous pensez que vous savez maintenant qu'il n'a pas besoin de libérer de ressources, mais comment savez-vous que dans le futur Morthstream ne changera pas sa mise en œuvre sous-jacente afin qu'elle utilise des ressources nécessaires à libérer en utilisant disposer ? Vous ne le faites pas, donc depuis que cela implémente idispotable , vous avez plus de code futur en utilisant simplement le modèle maintenant. Deuxièmement, et si vous modifiez votre code à l'avenir pour utiliser un type différent de qui a géré des ressources? En enveloppant le MemoryStream dans un à l'aide du bloc , vous réduisez maintenant les problèmes de maintenance à l'avenir; Encore une fois, c'est la bonne façon d'utiliser des objets, et spécifiquement flux S qui implémente Idisposable . Troisièmement, il s'agit d'un moyen clair de signaler aux lecteurs que vous avez terminé à l'aide de l'objet; Ce que les lecteurs de votre code s'attendent à voir lorsqu'ils voient que vous utilisez des objets qui implémentent Idisposable . Enfin, il s'agit de la mise en œuvre actuelle de MemoryStream.Dispose : xxx

Donc, cela marque le flux comme fermé, pas-écrit et pas-grotable. Si quelqu'un d'autre a eu une référence à une référence à la même référence Morthstream , il devient maintenant inutilisable pour eux qui pourrait être une bonne chose. Mais c'est vraiment la question la moins importante; Les détails de la mise en œuvre ne comptent pas.

Utilisez un à l'aide du bloc car Morthstream Implémente IDISPOABLE . N'utilisez pas de à l'aide de Block car vous pensez que MemoryStream n'a aucune ressource à libérer.


1 commentaires

Je suis d'accord avec cela et j'ai tellement voté, mais je mentionnerais également s'il vous plaît seulement envelopper des trucs dans l'utilisation de blocs que vous «possédez» que vous avez dérivé ou créé le flux dans la méthode de la méthode, rien n'est pire que de disposer de quelque chose de trois Les couches vers le bas, car éventuellement une personne essaiera de lire plus haut à partir d'un flux déjà fermé.