2010-11-11 3 views
22

La classe StreamReader possède à la fois la méthode close et la méthode élimination. Je veux savoir quelle méthode appeler pour nettoyer toutes les ressources.fermer ou disposer

Si j'utilise un bloc, je pense qu'il appellera sa méthode d'élimination. Sera-t-il suffisant pour nettoyer toutes les ressources?

+1

http://stackoverflow.com/q/61092/102112 – Alex

Répondre

22

Le bloc using appelle le Dispose() sur l'instance StreamReader. En règle générale, si un type est IDisposable, vous devriez le mettre dans using portée.

EDIT: Si vous regardez la mise en œuvre de Close()StreamReader utilisant réflecteur, vous verrez que qu'il appelle Dispose(true). Donc, si vous n'utilisez pas la portée using, appeler manuellement le Close() serait le même que d'appeler le Dispose() dans ce cas particulier.

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if ((this.Closable && disposing) && (this.stream != null)) 
     { 
      this.stream.Close(); 
     } 
    } 
    finally 
    { 
     if (this.Closable && (this.stream != null)) 
     { 
      this.stream = null; 
      this.encoding = null; 
      this.decoder = null; 
      this.byteBuffer = null; 
      this.charBuffer = null; 
      this.charPos = 0; 
      this.charLen = 0; 
      base.Dispose(disposing); 
     } 
    } 
} 
+0

fermer les appels dispose (vrai), utilisera-t-on aussi appelez-vous disposer (vrai)? – user496949

+0

Yup, ça va ... –

+0

Cela explique pourquoi si vous avez du code dans un 'using' avec un appel à' Close() ', en exécutant l'analyse de code de Visual Studio, vous obtiendrez' CA2202 \t Ne jetez pas les objets plusieurs fois' - parce que 'Close()' dispose déjà, et 'using' finira par essayer de se débarrasser de l'objet. Je me demande, alors ... pourquoi nous ne sommes pas vraiment confrontés à 'System.ObjectDisposedException'. – Veverke

1

Le bloc using est tout ce dont vous avez besoin.

+0

L'utilisation garantira l'appel. Est-ce la même chose que d'appeler à proximité? – user496949

+0

disposer implicitement fermer le flux –

16

Dispose est suffisant et est essentiel, car il appellera Close tout seul et effectuera plus de choses que Close ne fera pas.

L'utilisation du bloc est un moyen élégant de disposer si oui, utilisez-le autant que possible.

+0

N'est-ce pas l'inverse, c'est à dire. close appellera disposer? –

+0

@Backwards_Dave non, ce sera une grave erreur pour un objet de se disposer. Vous pouvez toujours vouloir utiliser l'instance après l'avoir fermée. –

+3

Dans la classe TextReader (le parent de StreamReader), l'implémentation des méthodes 'Close()' et 'Dispose()' est identique et appelle 'Dispose (true)'. Dans la classe StreamReader, 'Close()' appelle le 'Dispose (true)' qui annule l'objet. Par conséquent, dans ce cas, il est correct de dire que 'Close' appelle' Dispose'. –

0

Si vous souhaitez plus d'informations sur using, jetez un coup d'oeil ici

Using

Citation du site:

L'instruction à l'aide permet au programmeur de spécifier lorsque des objets que les ressources d'utilisation devraient libérer eux. L'objet fourni à l'instruction doit implémenter l'interface IDisposable . Cette interface fournit la méthode Dispose, qui doit libérer les ressources de l'objet.

0

Il semble y avoir certaines inquiétudes quant à savoir si Dispose fait correctement son travail.

Essentiellement - vous pouvez être assez certain que rien dans la BCL (Base Class Library) qui met en œuvre IDisposable va se ranger correctement lorsque Éliminez est appelé - par exemple quand une instruction à l'aide est hors de portée.

S'il y avait des problèmes avec les flux n'étant pas fermés, ils auraient été ramassés maintenant - vous pouvez faire confiance à IDisposable. C'est lorsque vous utilisez d'autres bibliothèques que vous comptez sur l'implémentation Dispose.

1

Utilisation Éliminer à l'aide d'un bloc utilisateur pour garantir le nettoyage.

Utilisez Fermer si vous avez terminé avec l'objet considérablement avant la fin du bloc d'utilisation, pour être aussi prompt que possible en libérant toutes les ressources.

Les deux vont donc fonctionner main dans la main, même si ces derniers peuvent être redondants si vous voulez atteindre la fin du bloc en quelques nanosecondes de toute façon.

3

Nous savons tous System.IO.StreamReader n'est pas la seule classe .NET 4.0+ qui implémente IDisposable et une méthode Close(). Pour le cas de StreamReader dans cette question, le code source montre que la classe de base TextReader.Close(), TextReader.Dispose() les deux courent les mêmes lignes de code. Vous pouvez également voir dans le code que TextReader.Dispose() est l'implémentation pour quand vous appelez StreamReader.Dispose() (parce que StreamReader ne remplace pas cette signature de surcharge de méthode de Dispose).

donc un appel à StreamReader.Dispose() se déroulera this inherited line of code, qui appelle la méthode protected override StreamReader.Dispose(disposing: true) et il en sera StreamReader.Close() appel StreamReader.Dispose(disposing: true). Donc, pour le cas de StreamReader, Close() et Dispose() se produisent pour exécuter les mêmes lignes de code.

Une réponse plus générale, non spécifique à la classe à la question de Close() ou Dispose()?, pourrait être de noter que Microsoft a assez clair documentation on implementing IDisposable and the Dispose pattern. Une lecture rapide est suffisante pour vous montrer que l'implémentation d'une méthode Close() n'est pas une exigence du modèle Dispose.

Imho la raison de trouver la méthode Close() sur tant de classes qui implémentent IDisposable, est le résultat de la convention, pas exigence.

Quelqu'un a commenté

Close and Dispose - which to call?

Un exemple d'une autre classe qui implémente IDisposable avec le modèle Dispose, et a une méthode Close(). Est-ce que Close() utilise le même code que Dispose() dans ce cas? Je n'ai pas regardé le code source, mais je ne le dirais pas nécessairement.

Questions connexes