Partilhar via


Exceções do Windows Workflow Foundation

Os fluxos de trabalho podem utilizar a TryCatch atividade para processar exceções geradas durante a execução de um fluxo de trabalho. Estas exceções podem ser processadas ou podem ser reproduzidas através da Rethrow atividade. As atividades na Finally secção são executadas quando a Try secção ou a Catches secção é concluída. Os fluxos de trabalho alojados por uma WorkflowApplication instância também podem utilizar o OnUnhandledException processador de eventos para processar exceções que não são processadas por uma TryCatch atividade.

Causas das Exceções

Num fluxo de trabalho, podem ser geradas exceções das seguintes formas:

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

  • Uma exceção explícita emitida pelo fluxo de trabalho com a Throw atividade .

  • Uma exceção .NET Framework 4.6.1 emitida a partir de uma atividade.

  • Uma exceção emitida a partir de código externo, como bibliotecas, componentes ou serviços utilizados no fluxo de trabalho.

Processamento de Exceções

Se uma exceção for emitida por uma atividade e não for processada, o comportamento predefinido é terminar a instância do fluxo de trabalho. Se um processador personalizado OnUnhandledException estiver presente, pode substituir este comportamento predefinido. Este processador dá ao autor do anfitrião do fluxo de trabalho a oportunidade de fornecer o processamento adequado, como o registo personalizado, abortar o fluxo de trabalho, cancelar o fluxo de trabalho ou terminar o fluxo de trabalho. Se um fluxo de trabalho gerar uma exceção que não é processada, o OnUnhandledException processador é invocado. Existem três ações possíveis devolvidas a partir das OnUnhandledException quais determinam o resultado final do fluxo de trabalho.

  • Cancelar – uma instância de fluxo de trabalho cancelada é uma saída correta de uma execução de ramo. Pode modelar o comportamento de cancelamento (por exemplo, através de uma atividade CancellationScope). O processador Concluído é invocado quando o processo de cancelamento é concluído. Um fluxo de trabalho cancelado está no estado Cancelado.

  • Terminar – não é possível retomar ou reiniciar uma instância de fluxo de trabalho terminada. Isto aciona o evento Concluído no qual pode fornecer uma exceção como o motivo pelo qual foi terminado. O processador Terminado é invocado quando o processo de terminação é concluído. Um fluxo de trabalho terminado está no estado Com falhas.

  • Abortar – uma instância de fluxo de trabalho abortada só pode ser retomada se tiver sido configurada para ser persistente. Sem persistência, não é possível retomar um fluxo de trabalho. No momento em que um fluxo de trabalho é abortado, todo o trabalho realizado (na memória) desde o último ponto de persistência será perdido. Para um fluxo de trabalho abortado, o processador Abortado é invocado com a exceção como o motivo pelo qual o processo de abortação é concluído. No entanto, ao contrário de Cancelado e Terminado, o processador Concluído não é invocado. Um fluxo de trabalho abortado está num estado Abortado.

O exemplo seguinte invoca um fluxo de trabalho que gera uma exceção. A exceção não é processada pelo fluxo de trabalho e o OnUnhandledException processador é invocado. Os WorkflowApplicationUnhandledExceptionEventArgs são inspecionados para fornecer informações sobre a exceção e o fluxo de trabalho é terminado.

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

Processar Exceções com a Atividade TryCatch

O processamento de exceções dentro de um fluxo de trabalho é efetuado com a TryCatch atividade. A TryCatch atividade tem uma Catches coleção de Catch atividades que estão associadas a um tipo específico Exception . Se a exceção emitida por uma atividade contida na Try secção de uma TryCatch atividade corresponder à exceção de uma Catch<TException> atividade na Catches coleção, a exceção é processada. Se a exceção for explicitamente reproduzida ou for emitida uma nova exceção, esta exceção passa para a atividade principal. O exemplo de código seguinte mostra uma TryCatch atividade que processa uma ApplicationException que é emitida na Try secção por uma Throw atividade. A mensagem da exceção é escrita na consola pela Catch<TException> atividade e, em seguida, é escrita uma mensagem na consola da Finally secção.

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 Finally secção são executadas quando a Try secção ou a Catches secção é concluída com êxito. A Try secção é concluída com êxito se não forem emitidas exceções a partir da mesma e a Catches secção for concluída com êxito se não forem emitidas exceções ou forem novamente lançadas a partir da mesma. Se for emitida uma exceção na Try secção de um TryCatch e não for processada por um Catch<TException> na Catches secção ou for novamente colocada a partir do Catches, as atividades na Finally não serão executadas, a menos que ocorra uma das seguintes.

Processamento de Exceções versus Compensação

A diferença entre o processamento de exceções e a compensação é que o processamento de exceções ocorre durante a execução de uma atividade. A compensação ocorre depois de uma atividade ter sido concluída com êxito. O processamento de exceções proporciona uma oportunidade de limpeza após a atividade gerar a exceção, enquanto a compensação fornece um mecanismo através do qual o trabalho concluído com êxito de uma atividade previamente concluída pode ser anulado. Para obter mais informações, consulte Compensação.

Ver também