Compartilhar via


Exceções do Windows Workflow Foundation

Fluxos de trabalho podem usar a atividade de TryCatch para manipular exceções que são geradas durante a execução de um fluxo de trabalho. Essas exceções podem ser tratados ou que podem ser lançadas usando a atividade de Rethrow . As atividades na seção de Finally são executadas quando a seção de Try ou a seção de Catches concluírem. Fluxos de trabalho hospedados por uma instância de WorkflowApplication também podem usar o manipulador de eventos OnUnhandledException para manipular exceções que não são manipuladas por uma atividade de TryCatch.

Causas de exceções

Em um fluxo de trabalho, exceções podem ser geradas das seguintes maneiras:

  • Um tempo limite de transações em TransactionScope.

  • Uma exceção lançada explícita pelo fluxo de trabalho usando a atividade de Throw .

  • Uma exceção do .NET Framework 4.6.1 lançada por uma atividade.

  • Uma exceção acionada de código externo, como bibliotecas, componentes, ou serviços que são usados no fluxo de trabalho.

Tratando exceções

Se uma exceção é acionada por uma atividade e é não tratada, o comportamento padrão é finalizar a instância de fluxo de trabalho. Se um manipulador de OnUnhandledException personalizado estiver presente, pode substituir esse comportamento padrão. Esse manipulador fornece o autor do host de fluxo de trabalho uma oportunidade para fornecer tratamento apropriado, como o log personalizado, anulando o fluxo de trabalho, cancelar o fluxo de trabalho, ou de terminação o fluxo de trabalho. Se um fluxo de trabalho gerencie uma exceção que não é tratada, o manipulador de OnUnhandledException é chamado. Há três ações possíveis retornadas de OnUnhandledException que determinam o resultado final de fluxo de trabalho.

  • Cancelar – Uma instância cancelada de fluxo de trabalho é uma saída graciosa da execução de uma ramificação. Você pode modelar o comportamento de cancelamento (por exemplo, usando uma atividade CancellationScope). O manipulador concluído é chamado quando o processo de cancelamento completa. Um fluxo de trabalho cancelado está no estado cancelado.

  • Terminar – Uma instância finalizada de fluxo de trabalho não pode ser continuada ou reiniciada. Isso dispara o evento concluído em que você pode fornecer uma exceção que a razão ele foi finalizada. O manipulador encerrado é chamado quando o processo de fim completa. Um fluxo de trabalho encerrado está no estado criticado.

  • Anular – Instâncias anuladas de um fluxo de trabalho podem ser continuadas somente se foram configuradas para serem persistentes. Sem persistência, um fluxo de trabalho não pode ser continuado. No ponto um fluxo de trabalho é anuladas, alguns funciona feito (na memória) como o ponto que o último de persistência será perdido. Para um fluxo de trabalho anuladas, o manipulador anuladas é chamado usando a exceção como a razão quando o processo de abort completa. No entanto, diferentemente de cancelado e de finalizado, o manipulador concluído não é chamado. Um fluxo de trabalho anuladas está em um estado anuladas.

O exemplo a seguir chama um fluxo de trabalho que gerencia uma exceção. A exceção é não tratados pelo fluxo de trabalho e o manipulador de OnUnhandledException é chamado. WorkflowApplicationUnhandledExceptionEventArgs é inspecionado para fornecer informações sobre a exceção, e fluxo de trabalho é encerrado.

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();

Manipulando exceções com a atividade de TryCatch

Manipulando exceções dentro de um fluxo de trabalho é executado pela atividade de TryCatch . A atividade de TryCatch tem uma coleção de Catches de atividades de Catch que são associadas com um tipo específico de Exception . Se a exceção acionada por uma atividade que está contida na seção de Try de uma atividade de TryCatch corresponde a exceção de uma atividade de Catch<TException> na coleção de Catches , então a exceção é tratada. Se a exceção é lançada novamente ou explicitamente uma nova exceção é lançada então passa essa exceção até a atividade pai. O exemplo de código a seguir mostra uma atividade de TryCatch que manipula ApplicationException que é gerada na seção de Try por uma atividade de Throw . A mensagem de exceção é escrita para o console pela atividade de Catch<TException> , e uma mensagem é gravada no console na seção de 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."
    }
};

As atividades na seção de Finally são executadas quando a seção de Try ou a seção de Catches completa com êxito. A seção de Try concluída com êxito se nenhuma exceção é lançada deles, e a seção de Catches concluída com êxito se nenhuma exceção é lançada ou rethrown deles. Se uma exceção é lançada na seção de Try de TryCatch e não é tratada por Catch<TException> na seção de Catches , nem é rethrown de Catches, as atividades em Finally não serão executadas a menos que o da seguir ocorrer.

Manipulação de exceção com a compensação

A diferença entre a manipulação de exceção e a compensação é que a manipulação de exceção ocorre durante a execução de uma atividade. A compensação ocorre após uma atividade terminou com êxito. Manipulação de exceção fornece uma oportunidade para limpar após a atividade gerencie a exceção, enquanto a compensação fornece um mecanismo por que o trabalho com êxito concluído de uma atividade anteriormente pode ser concluída desfeito. Para obter mais informações, confira Compensação.

Confira também