2010-06-15 6 views
1

Considérons le code:VB.NET: question sur « l'aide » bloc

On Error Goto ErrorHandler 

Using sr As StreamReader = New StreamReader(OpenFile) 
    str = sr.ReadToEnd 
    sr.Close() 
End Using 

Exit Sub 

ErrorHandler: 

S'il y a une erreur dans le bloc Using comment voulez-vous nettoyer l'objet sr?

L'objet sr n'est pas dans la portée dans ErrHandler, donc sr.Close() ne peut pas être appelé. Est-ce que le bloc Using nettoie automatiquement les ressources même s'il y a une erreur?

+2

Il semble que vous ayez manqué le point du bloc 'Using' ... –

+0

@Dan: Je comprends que la variable du bloc using sera seulement dans la portée du bloc using, je ne savais pas comment beaucoup de nettoyage serait fait et si Close() serait appelé. – CJ7

Répondre

1

Oui, le bloc à l'aide appellera automatiquement IDisposable.Dispose (qui, pour une StreamReader est la même chose que d'appeler Close) donc il n'y a rien que vous devez faire (c'est le point entier d'utiliser des blocs!)

+0

que se passe-t-il s'il y a une erreur pendant le bloc Using? Appellera-t-il encore Close()? – CJ7

+1

Oui, c'est ce que le but du bloc utilisant est. Chaque fois que l'exécution du programme quitte le bloc, elle appelle Dispose. – Thorarin

4

Comme codeka dit, vous n'avez pas besoin d'appeler Close sur sr. Il sera appelé automatiquement, et cela inclut s'il y a une erreur. L'utilisation de l'instruction using vous donne les mêmes fonctionnalités que try ... finally ... end try.

Et comme vous le voyez dans les réponses à votre autre question, vous ne devriez pas utiliser On Error etc juste faire:

Try 
    Using sr as StreamReader ... 
    ... 
    End Using 
Catch ex as SomeException 
... 
End Try 
+2

+10 si je pouvais pour ** vous ne devriez pas utiliser On Error ** –

1

Ce code:

Using sr As StreamReader = New StreamReader(OpenFile) 
    str = sr.ReadToEnd 
    sr.Close() 
End Using 

Est-ce vraiment équivalent à ceci:

Dim sr As StreamReader = Nothing 
Try 
    sr = New StreamReader(OpenFile) 
    sr.Close() ' notice: unnecessary ' 
Finally 
    sr.Close() 
End Try 

Gardez à l'esprit que le code dans un bloc Finally sera exécute toujours avant que la méthode ne retourne (si elle lance une exception, bien, alors vous êtes dans un monde de mal). Donc la ligne sr.Close que vous avez dans votre bloc Using est superflue (notez qu'il est inutile dans le code équivalent utilisant Try/Finally car sr.Close sera appelé dans le Finally n'importe quoi - exception levée ou non).

+0

N'appelle-t-il pas Dispose(), qui à son tour appelle Close()? – Panzercrisis

+0

@Panzercrisis: Oui, je le crois. Cela fait un moment que je ne me souviens pas si je le savais au moment où j'ai écrit cette réponse ou non! Je pense que je l'ai fait, et je me suis senti comme si c'était un détail plutôt mineur. La réponse acceptée semble l'indiquer explicitement. –