Исключения Windows Workflow Foundation

Рабочие процессы могут использовать действие TryCatch для обработки исключений, возникающих в ходе выполнения рабочего процесса. Эти исключения обрабатываются либо вызываются повторно при помощи действия Rethrow. Действия в разделе Finally выполняются при завершении либо раздела Try, либо раздела Catches. Рабочие процессы, размещенные экземпляром WorkflowApplication , также могут использовать OnUnhandledException обработчик событий для обработки исключений, которые не обрабатываются действием TryCatch .

Причины исключений

в рабочем процессе исключения могут создаваться следующим образом:

  • Время ожидания транзакций в TransactionScope.

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

  • Исключение платформа .NET Framework 4.6.1, вызванное действием.

  • Исключение, возникающее из внешнего кода, например из библиотек, компонентов или служб, используемых в рабочем процессе.

Обработка исключений

Если исключение возникает из действия и не обрабатывается, поведение по умолчанию состоит в завершении экземпляра рабочего процесса. Если присутствует пользовательский обработчик OnUnhandledException, он может переопределить поведение по умолчанию. Обработчик предоставляет автору узла рабочего процесса возможность выполнить соответствующую обработку, например пользовательское протоколирование, прерывание, отмену или прекращение рабочего процесса. Если рабочий процесс создает необрабатываемое исключение, вызывается обработчик OnUnhandledException. Метод OnUnhandledException может вернуть три действия, определяющие окончательный результат рабочего процесса.

  • Отмена . Отмененный экземпляр рабочего процесса является корректной остановкой выполнения ветви. Поведение отмены можно моделировать (например, с помощью действия CancellationScope). После завершения процесса отмены вызывается обработчик завершения (Completed). Отмененный рабочий процесс находится в состоянии Cancelled (Отменено).

  • Завершить — завершенный экземпляр рабочего процесса не может быть возобновлен или перезапущен. Формируется событие Completed (Завершено), в котором вы можете указать исключение, являющееся причиной. После завершения процесса вызывается обработчик завершения (Terminated). Завершенный рабочий процесс находится в состоянии ошибки (Faulted).

  • Прерывание — прерванные экземпляры рабочего процесса могут быть возобновлены, только если они настроены как постоянные. Без сохраняемости рабочий процесс нельзя возобновить. На этой стадии рабочий процесс прерывается, любые результаты работы (в памяти) с момента последнего сохранения будут потеряны. Для прерванного рабочего процесса вызывается обработчик прерывания (Aborted) с использованием исключения как основания, когда процесс прерывания завершается. Однако в отличие от обработчиков Cancelled и Terminated обработчик Completed не вызывается. Прерванный рабочий процесс находится в состоянии Aborted (Прервано).

В следующем примере кода вызывается рабочий процесс, в котором создается исключение. Исключение не обрабатывается рабочим процессом, и вызывается обработчик OnUnhandledException. Чтобы получить сведения об исключении, проверяются аргументы WorkflowApplicationUnhandledExceptionEventArgs, и рабочий процесс завершается.

Activity wf = new Sequence
{
    Activities =
     {
         new WriteLine
         {
             Text = "Starting the workflow."
         },
         new Throw
        {
            Exception = new InArgument<Exception>((env) =>
                new ApplicationException("Something unexpected happened."))
        },
        new WriteLine
         {
             Text = "Ending the workflow."
         }
     }
};

WorkflowApplication wfApp = new WorkflowApplication(wf);

wfApp.OnUnhandledException = delegate (WorkflowApplicationUnhandledExceptionEventArgs e)
{
    // Display the unhandled exception.
    Console.WriteLine("OnUnhandledException in Workflow {0}\n{1}",
        e.InstanceId, e.UnhandledException.Message);

    Console.WriteLine("ExceptionSource: {0} - {1}",
        e.ExceptionSource.DisplayName, e.ExceptionSourceInstanceId);

    // Instruct the runtime to terminate the workflow.
    return UnhandledExceptionAction.Terminate;

    // Other choices are UnhandledExceptionAction.Abort and
    // UnhandledExceptionAction.Cancel
};

wfApp.Run();

Обработка исключений при помощи действия TryCatch

Обработка исключений внутри рабочего процесса выполняется при помощи действия TryCatch. Действие TryCatch имеет коллекцию Catches действий Catch, из которых каждое связано с определенным типом Exception. Если исключение, возникшее из действия, содержащегося в разделе Try действия TryCatch, совпадает с исключением действия Catch<TException> в коллекции Catches, то исключение будет обработано. Если исключение возникает повторно явным образом или если возникает новое исключение, то это исключение передается родительскому действию. В следующем примере кода показано действие TryCatch, которое обрабатывает исключение ApplicationException, вызванное в разделе Try в результате действия Throw. Сообщение исключения записывается в консоль действием Catch<TException>, после чего сообщение выводится на консоль в разделе Finally.

DelegateInArgument<ApplicationException> ex = new DelegateInArgument<ApplicationException>()
{
    Name = "ex"
};

Activity wf = new TryCatch
{
    Try = new Throw()
    {
        Exception = new InArgument<Exception>((env) => new ApplicationException("An ApplicationException was thrown."))
    },
    Catches =
    {
        new Catch<ApplicationException>
        {
            Action = new ActivityAction<ApplicationException>
            {
                Argument = ex,
                Handler = new WriteLine()
                {
                    Text = new InArgument<string>((env) => ex.Get(env).Message)
                }
            }
        }
    },
    Finally = new WriteLine()
    {
        Text = "Executing in Finally."
    }
};

Действия в разделе Finally выполняются при успешном завершении либо раздела Try, либо раздела Catches. Раздел Try успешно завершается при отсутствии исключений из него, а раздел Catches успешно завершается, если не создаются собственные исключения и не вызываются из него повторно. При возникновении исключения в разделе Try блока TryCatch, которое либо не обрабатывается обработчиком Catch<TException> в разделе Catches, либо повторно вызывается из Catches, действия из раздела Finally не будут выполнены, если только не возникнет одна из следующих ситуаций.

  • Исключение перехватывается действием более высокого уровня TryCatch в рабочем процессе независимо от того, вызывается ли повторно с более высокого уровня TryCatch.

  • Исключение, не обработанное более высоким уровнем TryCatch, покидает корневой элемент рабочего процесса, и рабочий процесс используется для отмены вместо завершения или прерывания транзакции. Рабочие процессы, размещенные с помощью WorkflowApplication, могут настроить это путем обработки OnUnhandledException, после чего будет возвращено значение Cancel. Пример обработки OnUnhandledException приведен ранее в этом разделе. Службы Workflow Services можно настроить, используя WorkflowUnhandledExceptionBehavior и задавая Cancel. Пример настройки WorkflowUnhandledExceptionBehaviorсм. в разделе Расширяемость узла службы рабочего процесса.

Обработка исключений и компенсация

Отличие между обработкой исключений и компенсацией заключается в том, что обработка исключений имеет место во время выполнения действия. Компенсация имеет место после успешного завершения действия. Обработка исключений предоставляет возможность выполнить очистку после того, как действие вызывает исключение, в то время как компенсация обеспечивает механизм, с помощью которого можно отменить успешно завершенную работу ранее завершенного действия. Дополнительные сведения см. в разделе Компенсация.

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