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.
A exceção é detetada por uma atividade de nível TryCatch superior no fluxo de trabalho, independentemente de ser novamente obtida a partir desse nível TryCatchsuperior.
A exceção não é processada por um nível TryCatchsuperior , escapa à raiz do fluxo de trabalho e o fluxo de trabalho está configurado para cancelar em vez de terminar ou abortar. Os fluxos de trabalho alojados com WorkflowApplication podem configurá-lo ao processar OnUnhandledException e devolver Cancel. Um exemplo de processamento OnUnhandledException é fornecido anteriormente neste tópico. Os serviços de fluxo de trabalho podem configurá-lo ao utilizar WorkflowUnhandledExceptionBehavior e especificar Cancel. Para obter um exemplo de configuração WorkflowUnhandledExceptionBehaviordo , veja Extensibilidade do Anfitrião do Serviço de Fluxo de Trabalho.
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.