121 votes

Qu'advient-il si je retourne avant la fin de l'utilisation de la déclaration? Va les disposer être appelé?

J'ai le code suivant

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

L' dispose() méthode est appelée à la fin de l' using déclaration des accolades } droit? Depuis que j' return avant la fin de l' using énoncé, l' MemoryStream objet être éliminés correctement? Ce qui se passe ici?

178voto

Randolpho Points 36512

Oui, Dispose sera appelée. Il est appelé dès que l'exécution laisse le champ d'application de l' using bloc, indépendamment de ce qui signifie qu'il a fallu pour quitter le bloc, que ce soit la fin de l'exécution du bloc, return déclaration, ou une exception.

@Noldorin souligne à juste titre, à l'aide d'un using bloc de code est compilé en try/finally, Dispose appelée dans l' finally bloc. Par exemple le code suivant:

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

devient:

MemoryStream ms = new MemoryStream();
try
{
    // code
    return 0;
}
finally
{
    ms.Dispose();
}

Donc, parce qu' finally est garanti pour exécuter après l' try bloc a fini de l'exécution, quel que soit son chemin d'exécution, Dispose est garanti pour être appelé, n'importe quoi.

Pour plus d'informations, voir cet article MSDN.

Addendum:
Juste un petit bémol à ajouter: parce qu' Dispose est garanti pour être appelé, c'est presque toujours une bonne idée pour s'assurer qu' Dispose jamais déclenche une exception lorsque vous implémentez IDisposable. Malheureusement, il y a certaines classes dans la bibliothèque de base qui ne jeter, dans certaines circonstances, lorsqu' Dispose est appelé -- je suis à la recherche à vous, WCF Service de Référence / Proxy Client! - et quand cela arrive, il peut être très difficile de traquer l'exception d'origine si Dispose a été appelée au cours d'une pile d'exception détendez-vous, depuis la première exception est avalé en faveur de la nouvelle exception générée par l' Dispose appel. Il peut être maddeningly frustrant. Ou est-ce frustrant exaspérante? L'un des deux. Peut-être les deux.

19voto

Adam Houldsworth Points 38632

using états se comportent exactement comme try ... finally blocs, de sorte que sera toujours exécuté sur un code de sortie des chemins. Cependant, je crois qu'ils sont soumis à l'rares et très rares situations dans lesquelles finally blocs ne sont pas appelés. Un exemple que je me souvienne, c'est que si le thread de premier plan des sorties alors que les threads d'arrière-plan sont actifs: tous les threads en dehors de la GC sont en pause, signification, finally blocs ne sont pas exécutées.

Évident edit: ils ont le même comportement en dehors de la logique qui leur permet de gérer IDisposable objets, d'oh.

Contenu Bonus: ils peuvent être empilés (où les types différents):

using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{

}

Et aussi délimité par des virgules (où les types sont les mêmes):

using (SqlCommand comm = new SqlCommand("", conn), 
       SqlCommand comm2 = new SqlCommand("", conn))
{

}

4voto

Otávio Décio Points 44200

Votre objet MemoryStream seront éliminés correctement, pas besoin de s'inquiéter à ce sujet.

3voto

RSolberg Points 17001

Avec l' using déclaration, l'objet sera détruit, indépendamment de la réalisation de chemin d'accès.

Pour aller plus loin...

0voto

Wil P Points 1831

Jetez un oeil à votre code dans le réflecteur après la compilation. Vous trouverez que le compilateur refactors le code pour s'assurer qu'disposer est appelée sur le flux.

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