Поделиться через


Оператор Try... Catch... Finally (Visual Basic)

Позволяет, не прерывая выполнение программы, обрабатывать некоторые или все возможные ошибки, которые могут возникать в конкретном блоке кода.

Try
    [ tryStatements ]
    [ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
    [ catchStatements ]
    [ Exit Try ] ]
[ Catch ... ]
[ Finally
    [ finallyStatements ] ]
End Try

Части

Термин

Определение

tryStatements

Необязательный. Один или несколько операторов, в которых может возникнуть ошибка. Могут быть составными операторами.

Catch

Необязательный. Разрешено использование нескольких блоков Catch. Если исключение возникает при обработке блока Try, то каждая инструкция Catch сравнивается в текстовом порядке, чтобы определить обрабатывает ли она это исключение, с exception, представляющим исключение, которое возникло.

exception

Необязательный. Любое имя переменной. Значение exception является значением возникшей ошибки. Используется оператором Catch для задания перехватываемой ошибки. Если аргумент опущен, инструкция Catch перехватывает все исключения.

type

Необязательный. Указывает тип класса фильтра. Если значение exception относится к типу, указанному параметром type, или к типу, производному от него, данный идентификатор становится привязкой к объекту исключения.

When

Необязательный. Инструкция Catch с предложением When перехватывает исключения, только если результат вычисления expression равен True. Предложение When используется только после проверки типа исключения, и expression может ссылаться на идентификатор, представляющий исключение.

expression

Необязательный. Должен однозначно приводиться к типу Boolean. Любое выражение, которое описывает универсальный фильтр. Обычно используется для фильтрации по номеру ошибки. Используется с зарезервированным словом When для определения условий, при которых будет перехватываться данная ошибка.

catchStatements

Необязательный. Операторы обработки ошибок, возникших в соответствующем блоке Try. Могут быть составными операторами.

Exit Try

Необязательный. Зарезервированное слово, которое разбивает структуру Try...Catch...Finally. Выполнение возобновляется с кода, непосредственно следующего за оператором End Try. Инструкция Finally будет по-прежнему выполняться. Не допускается в блоках Finally.

Finally

Необязательный. Блок Finally всегда выполняется по окончании выполнения любой части оператора Try...Catch.

finallyStatements

Необязательный. Операторы, выполняемые после выполнения всех остальных действий по обработке ошибки.

End Try

Завершает структуру Try...Catch...Finally.

Заметки

Если предполагается, что во время выполнения определенного раздела кода может возникнуть определенное исключение, то поместите код в блок Try и используйте блок Catch для сохранения управления и обработки возникшего исключения.

Оператор try-catch Try…Catch состоит из блока Try, за которым следует одно или несколько предложений Catch, в которых определяются обработчики для различных исключений. Когда текущее исключение выбрасывается в блоке Try, Visual Basic ищет оператор Catch, обрабатывающий исключение. Если не найден соответствующий оператор Catch, Visual Basic рассматривается метод, который вызвал текущий метод, и так далее вверх по стеку вызовов. Если блок Catch не найден, то среда Visual Basic отображает пользователю сообщение о необработанном исключении и останавливает выполнение программы.

Можно использовать более одного оператора Catch в операторе Try…Catch. В этом случае будет иметь значение порядок следования предложений Catch, поскольку предложения будут проверяться именно в этом порядке. Более общие исключения следует перехватывать после более частных.

Следующие условные операторы Catch являются наименее конкретными и будет перехватывать все исключения, производные от класса Exception. Как правило, следует использовать один из этих вариантов в качестве последнего блока Catch структуры Try...Catch...Finally после перехвата всех ожидаемых конкретных исключений. Поток управления никогда не достигает блока Catch, который следует за любым из этих вариантов.

  • type имеет значение Exception, например Catch ex As Exception.

  • Оператор не имеет переменной exception, например Catch.

Когда оператор Try…Catch…Finally вложен в другой блок Try , Visual Basic сначала проверяет каждый оператор Catch во внутреннем блоке Try . Если соответствующий оператор Catch не найден, поиск продолжается в операторах Catch внешнего блока Try…Catch…Finally.

Локальные переменные блока Try недоступны в блоке Catch, поскольку это отдельные блоки. Если нужно использовать переменную в нескольких блоках, то следует объявить ее вне структуры Try...Catch...Finally.

Совет

Оператор Try…Catch…Finally доступен также в качестве фрагмента кода IntelliSense.В Диспетчере фрагментов кода, разверните Шаблоны кода - If, For Each, Try Catch, Property, и т.д.и затем Обработка ошибок (исключения) .Дополнительные сведения см. в разделе Практическое руководство. Вставка фрагментов кода IntelliSense.

Блок finally

Если имеется одна или несколько инструкций, которые необходимо запустить до выхода из структуры Try, используйте блок Finally. Элемент управления передает в блок Finally только перед передачей из структуры Try…Catch. Это справедливо даже в том случае, если исключение возникает внутри структуры Try.

Finally Блок является полезным для запуска любой код, который должен выполняться, даже если есть исключение. Управление всегда передается блоку Finally независимо от того, как была выполнен выход из блока Try...Catch.

Код в блоке Finally выполняется, даже если ваш код встречает оператор Return в блоке Try или Catch. Элемент управления не передает из блока Try или блока Catch в соответствующий блок Finally в следующих случаях:

Не допускается явное перемещение выполнения в блок Finally. Недопустимо также перемещать выполнение блока Finally, кроме как через исключение.

Если инструкция Try не содержит ни одного блока Catch, то она должна содержать Finally.

Совет

Если не требуется перехватывать определенные исключения, оператор Using действует аналогично блоку Try…Finally и гарантирует освобождение ресурсов независимо от способа выхода из блока.Это справедливо даже в случае необработанного исключения.Дополнительные сведения см. в разделе Оператор Using (Visual Basic).

Аргументы исключения

Catch блокирует аргумент exception, который представляет собой экземпляр класса Exception или класса, производного от класса Exception. Экземпляр класса Exception соответствует возникшей в блоке Try ошибке.

Свойства объекта Exception помогают в определении причины и места возникновения исключений. Например, свойство StackTrace содержит список вызванных методов, которые привели к исключению, помогая обнаружить место возникновения ошибки в коде. Message возвращает сообщение, описывающее исключение. HelpLink возвращает ссылку на связанный файл справки. InnerException возвращает объектException , который вызвал текущее исключение, или оно возвращает Nothing, если нет никакой первоначальной Exception.

Соображения при использовании оператора Try…Catch

Используйте оператор Try…Catch только для сигнала о необычных или непредвиденных событиях программы. Это связано со следующими причинами:

  • Перехват исключений во время выполнения создает дополнительные накладные расходы и может быть медленнее, чем предварительная проверка чтобы избежать исключений.

  • Если блок Catch не обрабатывается правильно, исключение может не сообщаться правильно для пользователей.

  • Обработка исключений делает программы более сложным.

Не всегда требуется оператор Try…Catch для проверки возможного условия. В следующем примере проверяется, существует ли файл перед попыткой открыть его. Это уменьшает потребность перехвата исключения, созданного методом OpenText.

Private Sub TextFileExample(ByVal filePath As String)

    ' Verify that the file exists.
    If System.IO.File.Exists(filePath) = False Then
        Console.Write("File Not Found: " & filePath)
    Else
        ' Open the text file and display its contents.
        Dim sr As System.IO.StreamReader =
            System.IO.File.OpenText(filePath)

        Console.Write(sr.ReadToEnd)

        sr.Close()
    End If
End Sub

Убедитесь, что код в блоках Catch может надлежащим образом сообщить исключения для пользователей, через журналирование, безопасное с точки зрения потоков, или соответствующие сообщения. В противном случае исключения могут остаться незамеченными.

Ситуации с частичным доверием

В случаях частичного доверия, например, в приложении, размещенном в сетевом ресурсе, Try...Catch...Finally не перехватит исключения системы безопасности, возникающие перед обращением к методу, содержащему вызов. В следующем примере, если поместить его на общем ресурсе сервера и запустить оттуда, то возникнет ошибка « System.Security.SecurityException: Request Failed." Дополнительные сведения о ошибках безопасности см. в описании класса SecurityException.

Try
    Process.Start("https://www.microsoft.com")
Catch ex As Exception
    MsgBox("Can't load Web page" & vbCrLf & ex.Message)
End Try

В таких случаях частичного доверия необходимо поместить инструкцию Process.Start в отдельную Sub. Начальный вызов Sub не удастся. Это позволяет Try...Catch перехватить вызов перед началом выполнения Sub, которая содержит Process.Start, и создаст исключение безопасности.

Пример

В следующем примере показано структура оператора Try...Catch...Finally.

Public Sub TryExample()
    ' Declare variables.
    Dim x As Integer = 5
    Dim y As Integer = 0

    ' Set up structured error handling.
    Try
        ' Cause a "Divide by Zero" exception.
        x = x \ y

        ' This statement does not execute because program
        ' control passes to the Catch block when the
        ' exception occurs.
        MessageBox.Show("end of Try block")
    Catch ex As Exception
        ' Show the exception's message.
        MessageBox.Show(ex.Message)

        ' Show the stack trace, which is a list of methods
        ' that are currently executing.
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
    Finally
        ' This line executes whether or not the exception occurs.
        MessageBox.Show("in Finally block")
    End Try
End Sub

В следующем примере метод CreateException вызывает NullReferenceException. Код, создающий исключение, не входит в блок Try. Поэтому метод CreateException не обрабатывает исключение. Метод RunSample обрабатывает исключение, поскольку вызов метода CreateException находится в блоке Try.

Пример включает операторы Catch для нескольких типов исключений, отсортированные от наиболее конкретных к наиболее общим.

Public Sub RunSample()
    Try
        CreateException()
    Catch ex As System.IO.IOException
        ' Code that reacts to IOException.
    Catch ex As NullReferenceException
        MessageBox.Show("NullReferenceException: " & ex.Message)
        MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
    Catch ex As Exception
        ' Code that reacts to any other exception.
    End Try
End Sub

Private Sub CreateException()
    ' This code throws a NullReferenceException.
    Dim obj = Nothing
    Dim prop = obj.Name

    ' This code also throws a NullReferenceException.
    'Throw New NullReferenceException("Something happened.")
End Sub

Следующий пример показывает, как использовать оператор Catch When для фильтрации в условном выражении. Если при вычислении условного выражения получено значение True, выполняется код в блоке Catch .

Private Sub WhenExample()
    Dim i As Integer = 5

    Try
        Throw New ArgumentException()
    Catch e As OverflowException When i = 5
        Console.WriteLine("First handler")
    Catch e As ArgumentException When i = 4
        Console.WriteLine("Second handler")
    Catch When i = 5
        Console.WriteLine("Third handler")
    End Try
End Sub
' Output: Third handler

В следующем примере есть оператор Try…Catch , который содержится в блоке Try . Внутренний блок Catch выдает исключение, у которого для свойства InnerException задано исходное исключение. Внешний блок Catch сообщает свои собственные исключения и внутреннее исключение.

Private Sub InnerExceptionExample()
    Try
        Try
            ' Set a reference to a StringBuilder.
            ' The exception below does not occur if the commented
            ' statement is used instead.
            Dim sb As System.Text.StringBuilder
            'Dim sb As New System.Text.StringBuilder

            ' Cause a NullReferenceException.
            sb.Append("text")
        Catch ex As Exception
            ' Throw a new exception that has the inner exception
            ' set to the original exception.
            Throw New ApplicationException("Something happened :(", ex)
        End Try
    Catch ex2 As Exception
        ' Show the exception.
        Console.WriteLine("Exception: " & ex2.Message)
        Console.WriteLine(ex2.StackTrace)

        ' Show the inner exception, if one is present.
        If ex2.InnerException IsNot Nothing Then
            Console.WriteLine("Inner Exception: " & ex2.InnerException.Message)
            Console.WriteLine(ex2.StackTrace)
        End If
    End Try
End Sub

См. также

Ссылки

Err

Оператор Exit (Visual Basic)

Оператор On Error (Visual Basic)

Exception

Оператор Throw (Visual Basic)

Основные понятия

Рекомендации по использованию фрагментов кода IntelliSense

Обработка исключений (библиотека параллельных задач)

Другие ресурсы

Структурная обработка исключений в Visual Basic

Журнал изменений

Дата

Журнал

Причина

Апрель 2011

Реорганизовано и добавлены примечания и примеры.

Улучшение информации.