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

Предоставляет способ управления некоторыми или всеми возможными ошибками, которые могут возникнуть в данном блоке кода, при этом выполняется код.Provides a way to handle some or all possible errors that may occur in a given block of code, while still running code.

СинтаксисSyntax

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

КомпонентыParts

ТерминTerm ОпределениеDefinition
tryStatements Необязательный элемент.Optional. Операторы, в которых может возникнуть ошибка.Statement(s) where an error can occur. Может быть составным оператором.Can be a compound statement.
Catch Необязательный элемент.Optional. CatchРазрешено несколько блоков.Multiple Catch blocks permitted. Если при обработке блока возникает исключение, Try Каждая Catch инструкция проверяется в текстовом порядке, чтобы определить, обрабатывается ли исключение, и exception представляет исключение, которое было выдано.If an exception occurs when processing the Try block, each Catch statement is examined in textual order to determine whether it handles the exception, with exception representing the exception that has been thrown.
exception Необязательный элемент.Optional. Любое имя переменной.Any variable name. Начальное значение exception — это значение возникшей ошибки.The initial value of exception is the value of the thrown error. Используется с Catch для указания перехваченной ошибки.Used with Catch to specify the error caught. Если этот параметр опущен, Catch инструкция перехватывает любое исключение.If omitted, the Catch statement catches any exception.
type Необязательный элемент.Optional. Указывает тип фильтра класса.Specifies the type of class filter. Если значение относится к exception типу, заданному параметром type или производного типа, идентификатор привязывается к объекту исключения.If the value of exception is of the type specified by type or of a derived type, the identifier becomes bound to the exception object.
When Необязательный элемент.Optional. CatchОператор с When предложением перехватывает исключения только в том случае expression , если значение равно True .A Catch statement with a When clause catches exceptions only when expression evaluates to True. WhenПредложение применяется только после проверки типа исключения и expression может ссылаться на идентификатор, представляющий исключение.A When clause is applied only after checking the type of the exception, and expression may refer to the identifier representing the exception.
expression Необязательный элемент.Optional. Должен быть неявно преобразуемым в Boolean .Must be implicitly convertible to Boolean. Любое выражение, описывающее универсальный фильтр.Any expression that describes a generic filter. Обычно используется для фильтрации по номеру ошибки.Typically used to filter by error number. Используется с When ключевым словом для указания обстоятельств, при которых ошибка перехвачена.Used with When keyword to specify circumstances under which the error is caught.
catchStatements Необязательный элемент.Optional. Инструкции для управления ошибками, происходящими в связанном Try блоке.Statement(s) to handle errors that occur in the associated Try block. Может быть составным оператором.Can be a compound statement.
Exit Try Необязательный элемент.Optional. Ключевое слово, которое нарушает Try...Catch...Finally структуру.Keyword that breaks out of the Try...Catch...Finally structure. Выполнение возобновляется с помощью кода, непосредственно следующего за End Try оператором.Execution resumes with the code immediately following the End Try statement. FinallyИнструкция будет по-прежнему выполняться.The Finally statement will still be executed. Не допускается в Finally блоках.Not allowed in Finally blocks.
Finally Необязательный элемент.Optional. FinallyБлок всегда выполняется, когда выполнение покидает любую часть Try...Catch инструкции.A Finally block is always executed when execution leaves any part of the Try...Catch statement.
finallyStatements Необязательный элемент.Optional. Инструкции, которые выполняются после возникновения всех других ошибок обработки.Statement(s) that are executed after all other error processing has occurred.
End Try Завершает Try...Catch...Finally структуру.Terminates the Try...Catch...Finally structure.

КомментарииRemarks

Если предполагается, что конкретное исключение может возникнуть во время определенного раздела кода, разместите код в Try блоке и используйте Catch блок для удержания управления и обработайте исключение, если оно происходит.If you expect that a particular exception might occur during a particular section of code, put the code in a Try block and use a Catch block to retain control and handle the exception if it occurs.

Try…CatchОператор состоит из Try блока, за которым следует одно или несколько Catch предложений, которые задают обработчики для различных исключений.A Try…Catch statement consists of a Try block followed by one or more Catch clauses, which specify handlers for various exceptions. При возникновении исключения в Try блоке Visual Basic ищет Catch инструкцию, которая обрабатывает исключение.When an exception is thrown in a Try block, Visual Basic looks for the Catch statement that handles the exception. Если соответствующий Catch оператор не найден, Visual Basic проверяет метод, который вызвал текущий метод, и т. д. в стеке вызовов.If a matching Catch statement is not found, Visual Basic examines the method that called the current method, and so on up the call stack. Если Catch блок не найден, Visual Basic отображает пользователю сообщение о необработанном исключении и останавливает выполнение программы.If no Catch block is found, Visual Basic displays an unhandled exception message to the user and stops execution of the program.

В операторе можно использовать более одной Catch инструкции Try…Catch .You can use more than one Catch statement in a Try…Catch statement. В этом случае порядок Catch предложений важен, так как они анализируются по порядку.If you do this, the order of the Catch clauses is significant because they are examined in order. Перехватывайте более конкретные исключения перед менее конкретными.Catch the more specific exceptions before the less specific ones.

Следующие Catch условия инструкции являются наименее конкретными, и будут перехватывать все исключения, производные от Exception класса.The following Catch statement conditions are the least specific, and will catch all exceptions that derive from the Exception class. Обычно следует использовать один из этих вариантов в качестве последнего Catch блока в Try...Catch...Finally структуре после перехвата всех конкретных исключений.You should ordinarily use one of these variations as the last Catch block in the Try...Catch...Finally structure, after catching all the specific exceptions you expect. Поток управления никогда не может достичь Catch блока, который следует за одним из этих вариантов.Control flow can never reach a Catch block that follows either of these variations.

  • Например type Exception :Catch ex As ExceptionThe type is Exception, for example: Catch ex As Exception

  • Оператор не имеет exception переменной, например:CatchThe statement has no exception variable, for example: Catch

Если Try…Catch…Finally инструкция вложена в другой Try блок, Visual Basic сначала проверяет каждую Catch инструкцию во внутреннем Try блоке.When a Try…Catch…Finally statement is nested in another Try block, Visual Basic first examines each Catch statement in the innermost Try block. Если соответствующий Catch оператор не найден, поиск продолжается до Catch инструкций внешнего Try…Catch…Finally блока.If no matching Catch statement is found, the search proceeds to the Catch statements of the outer Try…Catch…Finally block.

Локальные переменные из Try блока недоступны в Catch блоке, так как они являются отдельными блоками.Local variables from a Try block are not available in a Catch block because they are separate blocks. Если вы хотите использовать переменную более чем в одном блоке, объявите переменную за пределами Try...Catch...Finally структуры.If you want to use a variable in more than one block, declare the variable outside the Try...Catch...Finally structure.

Совет

Try…Catch…FinallyИнструкция доступна в виде фрагмента кода IntelliSense.The Try…Catch…Finally statement is available as an IntelliSense code snippet. В диспетчере фрагментов кода разверните узел шаблоны кода — Если для каждого, попробуйте перехватить, свойство и т. д., а затем — Обработка ошибок (исключения).In the Code Snippets Manager, expand Code Patterns - If, For Each, Try Catch, Property, etc, and then Error Handling (Exceptions). Дополнительные сведения см. в статье Фрагменты кода.For more information, see Code Snippets.

Блок finallyFinally block

Если имеется одна или несколько инструкций, которые должны выполняться до выхода из Try структуры, используйте Finally блок.If you have one or more statements that must run before you exit the Try structure, use a Finally block. Управление передается Finally блоку непосредственно перед его передачей из Try…Catch структуры.Control passes to the Finally block just before it passes out of the Try…Catch structure. Это справедливо даже в том случае, если исключение происходит в любой точке Try структуры.This is true even if an exception occurs anywhere inside the Try structure.

FinallyБлок полезен для выполнения любого кода, который должен выполняться, даже если возникает исключение.A Finally block is useful for running any code that must execute even if there is an exception. Элемент управления передается Finally блоку независимо от того, как Try...Catch блок завершает работу.Control is passed to the Finally block regardless of how the Try...Catch block exits.

Код в Finally блоке выполняется, даже если код встречает Return инструкцию в Try Catch блоке или.The code in a Finally block runs even if your code encounters a Return statement in a Try or Catch block. Элемент управления не передается Try из Catch блока или в соответствующий Finally блок в следующих случаях:Control does not pass from a Try or Catch block to the corresponding Finally block in the following cases:

Не допускается явное перенаправление выполнения в Finally блок.It is not valid to explicitly transfer execution into a Finally block. Передача выполнения из Finally блока недопустима, за исключением исключения.Transferring execution out of a Finally block is not valid, except through an exception.

Если Try инструкция не содержит хотя бы один Catch блок, она должна содержать Finally блок.If a Try statement does not contain at least one Catch block, it must contain a Finally block.

Совет

Если не нужно перехватывать определенные исключения, Using инструкция ведет себя как Try…Finally блок и гарантирует утилизацию ресурсов независимо от того, как вы выйдете из блока.If you do not have to catch specific exceptions, the Using statement behaves like a Try…Finally block, and guarantees disposal of the resources, regardless of how you exit the block. Это справедливо даже при необработанном исключении.This is true even with an unhandled exception. Дополнительные сведения см. в разделе оператор using.For more information, see Using Statement.

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

CatchАргумент блока exception является экземпляром Exception класса или классом, производным от Exception класса.The Catch block exception argument is an instance of the Exception class or a class that derives from the Exception class. ExceptionЭкземпляр класса соответствует ошибке, произошедшей в Try блоке.The Exception class instance corresponds to the error that occurred in the Try block.

Свойства Exception объекта помогают определить причину и расположение исключения.The properties of the Exception object help to identify the cause and location of an exception. Например, StackTrace свойство перечисляет вызываемые методы, которые привели к исключению, помогая найти место возникновения ошибки в коде.For example, the StackTrace property lists the called methods that led to the exception, helping you find where the error occurred in the code. MessageВозвращает сообщение, описывающее исключение.Message returns a message that describes the exception. HelpLinkВозвращает ссылку на связанный файл справки.HelpLink returns a link to an associated Help file. InnerExceptionВозвращает Exception объект, который привел к текущему исключению, или возвращается Nothing при отсутствии исходного Exception .InnerException returns the Exception object that caused the current exception, or it returns Nothing if there is no original Exception.

Рекомендации по использованию try... Оператор catchConsiderations when using a Try…Catch statement

Используйте Try…Catch оператор, чтобы сообщить о возникновении необычных или непредвиденных событий программы.Use a Try…Catch statement only to signal the occurrence of unusual or unanticipated program events. К таким причинам относятся следующие.Reasons for this include the following:

  • Перехват исключений во время выполнения создает дополнительные издержки и, скорее всего, будет медленнее, чем Предварительная проверка, чтобы избежать исключений.Catching exceptions at runtime creates additional overhead, and is likely to be slower than pre-checking to avoid exceptions.

  • Если Catch блок обрабатывается неправильно, исключение может быть неправильно сообщено пользователям.If a Catch block is not handled correctly, the exception might not be reported correctly to users.

  • Обработка исключений делает программу более сложной.Exception handling makes a program more complex.

Не всегда требуется Try…Catch оператор для проверки условия, которое может произойти.You do not always need a Try…Catch statement to check for a condition that is likely to occur. В следующем примере проверяется, существует ли файл, прежде чем пытаться его открыть.The following example checks whether a file exists before trying to open it. Это уменьшает необходимость в перехвате исключения, вызываемого OpenText методом.This reduces the need for catching an exception thrown by the OpenText method.

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 блоках может правильно сообщать об исключениях пользователям, независимо от того, является ли он потокобезопасным или соответствующим сообщением.Ensure that code in Catch blocks can properly report exceptions to users, whether through thread-safe logging or appropriate messages. В противном случае исключения могут остаться неизвестными.Otherwise, exceptions might remain unknown.

Асинхронные методыAsync methods

Если метод помечается модификатором Async , можно использовать оператор await в методе.If you mark a method with the Async modifier, you can use the Await operator in the method. Оператор с Await оператором приостанавливает выполнение метода до тех пор, пока не завершится ожидаемая задача.A statement with the Await operator suspends execution of the method until the awaited task completes. Задача представляет выполняющуюся работу.The task represents ongoing work. Когда задача, связанная с Await оператором, завершается, выполнение возобновляется в том же методе.When the task that's associated with the Await operator finishes, execution resumes in the same method. Дополнительные сведения см. в разделе поток управления в асинхронных программах.For more information, see Control Flow in Async Programs.

Задача, возвращаемая асинхронным методом, может завершиться с ошибкой, что означает, что она завершилась из-за необработанного исключения.A task returned by an Async method may end in a faulted state, indicating that it completed due to an unhandled exception. Задача также может завершаться в отмененном состоянии, что приводит к OperationCanceledException возникновению исключения из выражения await.A task may also end in a canceled state, which results in an OperationCanceledException being thrown out of the await expression. Чтобы перехватить исключение любого типа, поместите Await выражение, связанное с задачей, в Try блок и перехватите исключение в Catch блоке.To catch either type of exception, place the Await expression that's associated with the task in a Try block, and catch the exception in the Catch block. Пример приведен далее в этом разделе.An example is provided later in this topic.

Задача может находиться в неисправном состоянии, так как за ее сбоем отвечает несколько исключений.A task can be in a faulted state because multiple exceptions were responsible for its faulting. Например, задача может быть результатом вызова метода Task.WhenAll.For example, the task might be the result of a call to Task.WhenAll. При ожидании такой задачи Перехваченное исключение является только одним из исключений, и вы не можете предсказать, какое исключение будет перехвачено.When you await such a task, the caught exception is only one of the exceptions, and you can't predict which exception will be caught. Пример приведен далее в этом разделе.An example is provided later in this topic.

AwaitВыражение не может находиться внутри Catch блока или Finally блока.An Await expression can't be inside a Catch block or Finally block.

IteratorsIterators

Функция итератора или Get метод доступа выполняет настраиваемую итерацию по коллекции.An iterator function or Get accessor performs a custom iteration over a collection. Итератор использует оператор yield для возвращения каждого элемента коллекции по одному за раз.An iterator uses a Yield statement to return each element of the collection one at a time. Для вызова функции-итератора используется оператор For Each... Следующий оператор.You call an iterator function by using a For Each...Next Statement.

YieldОператор может находиться внутри Try блока.A Yield statement can be inside a Try block. TryБлок, содержащий Yield оператор, может иметь Catch блоки и может иметь Finally блок.A Try block that contains a Yield statement can have Catch blocks, and can have a Finally block. Пример см. в разделе "пробные блоки в Visual Basic" итераторов .See the "Try Blocks in Visual Basic" section of Iterators for an example.

YieldОператор не может находиться внутри Catch блока или блока Finally .A Yield statement cannot be inside a Catch block or a Finally block.

Если For Each тело (за пределами функции итератора) создает исключение, Catch блок в функции итератора не выполняется, но Finally выполняется блок в функции iterator.If the For Each body (outside of the iterator function) throws an exception, a Catch block in the iterator function is not executed, but a Finally block in the iterator function is executed. CatchБлок внутри функции итератора перехватывает только исключения, происходящие внутри функции итератора.A Catch block inside an iterator function catches only exceptions that occur inside the iterator function.

Ситуации частичного доверияPartial-trust situations

В ситуациях частичного доверия, таких как приложение, размещенное в общей сетевой папке, не Try...Catch...Finally перехватывает исключения безопасности, происходящие до вызова метода, содержащего вызов.In partial-trust situations, such as an application hosted on a network share, Try...Catch...Finally does not catch security exceptions that occur before the method that contains the call is invoked. В следующем примере, когда вы помещаете его на серверный ресурс и выполняете его, вызывается ошибка "System. Security. SecurityException: запрос не выполнен".The following example, when you put it on a server share and run from there, produces the error "System.Security.SecurityException: Request Failed." Дополнительные сведения об исключениях безопасности см. в разделе SecurityException класс.For more information about security exceptions, see the SecurityException class.

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

В подобной ситуации частичного доверия необходимо разместить Process.Start оператор в отдельном Sub .In such a partial-trust situation, you have to put the Process.Start statement in a separate Sub. Начальный вызов метода Sub завершится ошибкой.The initial call to the Sub will fail. Это позволяет Try...Catch перехватить его перед Sub запуском, который содержит, Process.Start и созданным исключением безопасности.This enables Try...Catch to catch it before the Sub that contains Process.Start is started and the security exception produced.

ПримерыExamples

Структура try... Перехватить... СчетеThe structure of Try...Catch...Finally

В следующем примере показана структура Try...Catch...Finally инструкции.The following example illustrates the structure of the Try...Catch...Finally statement.

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

Исключение в методе, вызываемом из блока tryException in a method called from a Try block

В следующем примере CreateException метод создает исключение NullReferenceException .In the following example, the CreateException method throws a NullReferenceException. Код, создающий исключение, не находится в Try блоке.The code that generates the exception is not in a Try block. Поэтому CreateException метод не обрабатывает исключение.Therefore, the CreateException method does not handle the exception. RunSampleМетод обрабатывает исключение, так как вызов CreateException метода находится в Try блоке.The RunSample method does handle the exception because the call to the CreateException method is in a Try block.

Пример включает в себя Catch инструкции для нескольких типов исключений, упорядоченные от наиболее конкретных к наиболее общим.The example includes Catch statements for several types of exceptions, ordered from the most specific to the most general.

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 WhenThe Catch When statement

В следующем примере показано, как использовать Catch When инструкцию для фильтрации по условному выражению.The following example shows how to use a Catch When statement to filter on a conditional expression. Если условное выражение имеет значение True , код в Catch блоке выполняется.If the conditional expression evaluates to True, the code in the Catch block runs.

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

Вложенные операторы TryNested Try statements

В следующем примере содержится Try…Catch оператор, содержащийся в Try блоке.The following example has a Try…Catch statement that is contained in a Try block. Внутренний Catch блок создает исключение, InnerException для свойства которого задано исходное исключение.The inner Catch block throws an exception that has its InnerException property set to the original exception. Внешний Catch блок сообщает свое собственное исключение и внутреннее исключение.The outer Catch block reports its own exception and the inner exception.

Private Sub InnerExceptionExample()
    Try
        Try
            ' Set a reference to a StringBuilder.
            ' The exception below does not occur if the commented
            ' out 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

Обработка исключений для асинхронных методовException handling for async methods

В следующем примере демонстрируется обработка исключений для асинхронных методов.The following example illustrates exception handling for async methods. Чтобы перехватить исключение, которое применяется к асинхронной задаче, Await выражение находится в Try блоке вызывающего объекта, а исключение перехвачено в Catch блоке.To catch an exception that applies to an async task, the Await expression is in a Try block of the caller, and the exception is caught in the Catch block.

Раскомментируйте строку Throw New Exception в этом примере для демонстрации обработки исключений.Uncomment the Throw New Exception line in the example to demonstrate exception handling. Исключение перехвачено в Catch блоке, IsFaulted свойство задачи имеет значение True , а Exception.InnerException для свойства задачи задано исключение.The exception is caught in the Catch block, the task's IsFaulted property is set to True, and the task's Exception.InnerException property is set to the exception.

Раскомментируйте строку Throw New OperationCancelledException, чтобы показать, что происходит при отмене асинхронного процесса.Uncomment the Throw New OperationCancelledException line to demonstrate what happens when you cancel an asynchronous process. Исключение перехвачено в Catch блоке, а IsCanceled свойство задачи имеет значение True .The exception is caught in the Catch block, and the task's IsCanceled property is set to True. Однако при некоторых условиях, которые не применяются к этому примеру, параметру присваивается значение, а параметру присваивается IsFaulted True IsCanceled значение False .However, under some conditions that don't apply to this example, IsFaulted is set to True and IsCanceled is set to False.

Public Async Function DoSomethingAsync() As Task
    Dim theTask As Task(Of String) = DelayAsync()

    Try
        Dim result As String = Await theTask
        Debug.WriteLine("Result: " & result)
    Catch ex As Exception
        Debug.WriteLine("Exception Message: " & ex.Message)
    End Try

    Debug.WriteLine("Task IsCanceled: " & theTask.IsCanceled)
    Debug.WriteLine("Task IsFaulted:  " & theTask.IsFaulted)
    If theTask.Exception IsNot Nothing Then
        Debug.WriteLine("Task Exception Message: " &
            theTask.Exception.Message)
        Debug.WriteLine("Task Inner Exception Message: " &
            theTask.Exception.InnerException.Message)
    End If
End Function

Private Async Function DelayAsync() As Task(Of String)
    Await Task.Delay(100)

    ' Uncomment each of the following lines to
    ' demonstrate exception handling.

    'Throw New OperationCanceledException("canceled")
    'Throw New Exception("Something happened.")
    Return "Done"
End Function


' Output when no exception is thrown in the awaited method:
'   Result: Done
'   Task IsCanceled: False
'   Task IsFaulted:  False

' Output when an Exception is thrown in the awaited method:
'   Exception Message: Something happened.
'   Task IsCanceled: False
'   Task IsFaulted:  True
'   Task Exception Message: One or more errors occurred.
'   Task Inner Exception Message: Something happened.

' Output when an OperationCanceledException or TaskCanceledException
' is thrown in the awaited method:
'   Exception Message: canceled
'   Task IsCanceled: True
'   Task IsFaulted:  False

Обработка нескольких исключений в асинхронных методахHandling multiple exceptions in async methods

В следующем примере демонстрируется обработка исключений, когда несколько задач могут привести к нескольким исключениям.The following example illustrates exception handling where multiple tasks can result in multiple exceptions. TryБлок содержит Await выражение для Task.WhenAll возвращаемой задачи.The Try block has the Await expression for the task that Task.WhenAll returned. Задача завершится, когда будут выполнены три задачи, к которым Task.WhenAll применяется.The task is complete when the three tasks to which Task.WhenAll is applied are complete.

Каждая из трех задач вызывает исключение.Each of the three tasks causes an exception. CatchБлок проходит по исключениям, которые находятся в Exception.InnerExceptions свойстве Task.WhenAll возвращаемой задачи.The Catch block iterates through the exceptions, which are found in the Exception.InnerExceptions property of the task that Task.WhenAll returned.

Public Async Function DoMultipleAsync() As Task
    Dim theTask1 As Task = ExcAsync(info:="First Task")
    Dim theTask2 As Task = ExcAsync(info:="Second Task")
    Dim theTask3 As Task = ExcAsync(info:="Third Task")

    Dim allTasks As Task = Task.WhenAll(theTask1, theTask2, theTask3)

    Try
        Await allTasks
    Catch ex As Exception
        Debug.WriteLine("Exception: " & ex.Message)
        Debug.WriteLine("Task IsFaulted: " & allTasks.IsFaulted)
        For Each inEx In allTasks.Exception.InnerExceptions
            Debug.WriteLine("Task Inner Exception: " + inEx.Message)
        Next
    End Try
End Function

Private Async Function ExcAsync(info As String) As Task
    Await Task.Delay(100)

    Throw New Exception("Error-" & info)
End Function

' Output:
'   Exception: Error-First Task
'   Task IsFaulted: True
'   Task Inner Exception: Error-First Task
'   Task Inner Exception: Error-Second Task
'   Task Inner Exception: Error-Third Task

См. также разделSee also