2010-06-15 2 views
1

Рассмотрим код:VB.NET: вопрос об «использовании» блок

On Error Goto ErrorHandler 

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

Exit Sub 

ErrorHandler: 

Если есть ошибка внутри Using блока, как вы очистить вверх sr объект?

Объект sr не имеет значения в ErrHandler, поэтому sr.Close() не может быть вызван. Удаляет ли блок Using любые ресурсы автоматически, даже если есть ошибка?

+2

Кажется, что вам не хватает точки блока 'Using' ... –

+0

@Dan: Я понимаю, что переменная используемого блока будет только в области использования блока, я просто не был уверен, как будет проведена большая очистка и будет ли вызвана функция Close(). – CJ7

ответ

1

Да, используя блок будет автоматически вызывать IDisposable.Dispose (который, для StreamReader является такой же, как вызов Close), так что нет ничего, что нужно сделать (это вся точка использования блоков!)

+0

Что делать, если при использовании блока есть ошибка? Будет ли он по-прежнему вызывать Close()? – CJ7

+1

Да, это цель использования блока. Всякий раз, когда выполнение программы покидает блок, оно вызывает Dispose. – Thorarin

4

As codeka говорит, вам не нужно звонить Close на sr. Он будет вызываться автоматически, и это включает в себя ошибку. Использование оператора using дает вам такую ​​же функциональность, как try ... finally ... end try.

И, как вы видите, в ответах на ваш другой вопрос, вы не должны использовать On Error и т.д. просто сделать:

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

+10 если бы я мог для ** вы не должны использовать On Error ** –

1

Этот код:

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

Это действительно эквивалентно следующему:

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

Имейте в виду, что код внутри блока Finally будет всегда выполняет до того, как метод вернется (если он выдает исключение из своего собственного, ну, тогда вы попадете в мир боли). Таким образом, линия sr.Close у вас в вашем блоке Using является излишней (обратите внимание, что это необязательно в эквивалентном коде с использованием Try/Finally, так как sr.Close будет вызываться в Finally независимо от того, что - исключение выбрано или нет).

+0

Не вызывает ли Dispose(), который в свою очередь вызывает Close()? – Panzercrisis

+0

@Panzercrisis: Да, я так считаю. Это было какое-то время, поэтому я не помню, знал ли я это в то время, когда я написал этот ответ или нет! Я думаю, что так и делал, и мне казалось, что это была небольшая деталь. В принятом ответе явно указывается это. –