Exceptions Windows Workflow Foundation
Les flux de travail peuvent utiliser l'activité TryCatch pour gérer des exceptions déclenchées lors de leur exécution. Ces exceptions peuvent être gérées ou être à nouveau levées à l'aide de l'activité Rethrow. Les activités de la section Finally sont exécutées lorsque soit la section Try, soit la section Catches est terminée. Les workflows hébergés par une instance WorkflowApplication peuvent également utiliser le gestionnaire d’événements OnUnhandledException pour gérer des exceptions non prises en charge par une activité TryCatch.
Raisons des exceptions
Dans un workflow, les exceptions peuvent être générées des différentes manières suivantes :
délai d'expiration de transactions dans l'objet TransactionScope ;
exception explicite levée par le flux de travail à l'aide de l'activité Throw ;
exception .NET Framework 4.6.1 levée depuis une activité ;
exception levée par un code externe, tel que les bibliothèques, composants ou services utilisés dans le flux de travail.
Gestion des exceptions
Si une exception est levée par une activité et n'est pas gérée, le comportement par défaut consiste à arrêter l'instance de flux de travail. En cas de présence d'un gestionnaire OnUnhandledException personnalisé, il peut substituer ce comportement par défaut. Ce gestionnaire permet à l’auteur hôte du workflow de fournir la gestion appropriée, englobant par exemple l’enregistrement personnalisé, l’abandon de workflow, l’annulation de workflow ou l’arrêt de workflow. Si un workflow lève une exception qui n'est pas gérée, le gestionnaire OnUnhandledException est appelé. Il existe trois actions possibles retournées depuis OnUnhandledException qui déterminent les résultats finaux du flux de travail.
Annulation - Une instance annulée de flux de travail est une sortie normale d’une exécution de branche. Vous pouvez modéliser le comportement d’annulation (par exemple, en utilisant une activité CancellationScope). Le gestionnaire Completed est appelé lorsque le processus d'annulation se termine. Un flux de travail annulé est dans un état d'annulation.
Terminate - Une instance de flux de travail terminée ne peut pas être reprise ou redémarrée. Cela déclenche l'événement Completed dans lequel vous pouvez fournir une exception comme la raison de l'arrêt. Le gestionnaire Terminated est appelé lorsque le processus d'arrêt se termine. Un flux de travail terminé est dans l'état d'erreur.
Abandon - Une instance de flux de travail abandonnée peut reprendre uniquement si elle a été configurée pour être persistante. Sans persistance, un flux de travail ne peut pas être repris. Au stade où un flux de travail est abandonné, les tâches effectuées (en mémoire) depuis le dernier point de persistance sont perdues. Pour un workflow abandonné, le gestionnaire Aborted est appelé en utilisant l'exception comme raison lorsque le processus d'abandon est terminé. Toutefois, contrairement aux gestionnaires Cancelled et Terminated, le gestionnaire Completed n'est pas appelé. Un flux de travail abandonné est dans un état d'abandon.
L'exemple suivant appelle un workflow qui lève une exception. L'exception n'est pas prise en charge par le workflow et le gestionnaire OnUnhandledException est appelé. L'objet WorkflowApplicationUnhandledExceptionEventArgs est inspecté de façon à fournir des informations sur l'exception, et le workflow est arrêté.
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();
Gestion des exceptions avec l'activité TryCatch
La gestion des exceptions au sein d'un workflow est effectuée avec l'activité TryCatch. L’activité TryCatch possède une collection Catches des activités Catch qui sont toutes associées à un type Exception spécifique. Si l'exception levée par une activité contenue dans la section Try d'une activité TryCatch correspond à l'exception d'une activité Catch<TException> dans la collection Catches, elle est gérée. L'exception passe à l'activité parente si elle est explicitement à nouveau levée ou si une nouvelle exception est levée. L'exemple de code suivant illustre une activité TryCatch qui gère un objet ApplicationException levé dans la section Try par une activité Throw. Le message de l'exception est écrit sur la console par l'activité Catch<TException>, puis un message est écrit sur la console dans la section 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."
}
};
Les activités dans la section Finally sont exécutées lorsque soit la section Try, soit la section Catches est terminée correctement. La section Try se termine correctement si aucune exception n'est levée, et la section Catches se termine correctement si aucune exception n'est levée ou à nouveau levée. Si une exception est levée dans la section Try d'un TryCatch et n'est pas gérée par Catch<TException> dans la section Catches, ou est à nouveau levée dans Catches, les activités dans Finally ne seront pas exécutées à moins qu'une des opérations suivantes se produise.
L'exception est interceptée par une activité TryCatch de plus haut niveau dans le flux de travail, qu'elle soit levée de nouveau ou non à partir de cette activité TryCatch de niveau supérieur.
L'exception n'est pas gérée par une activité TryCatch de niveau supérieur, s'échappe de la racine du flux de travail et le flux de travail est configuré de sorte à annuler au lieu de terminer ou abandonner. Les flux de travail hébergés à l'aide de WorkflowApplication peuvent configurer cela en gérant OnUnhandledException et en retournant Cancel. Un exemple de gestion OnUnhandledException est disponible précédemment dans cette rubrique. Les services de flux de travail peuvent configurer cette opération à l'aide de WorkflowUnhandledExceptionBehavior et en spécifiant Cancel. Pour obtenir un exemple de configuration WorkflowUnhandledExceptionBehavior, consultez Extensibilité de l’hôte du service de flux de travail.
Gestion des exceptions et compensation
La différence entre la gestion des exceptions et la compensation réside dans le fait que la gestion des exceptions a lieu lors de l'exécution d'une activité. La compensation a lieu une fois une activité terminée correctement. La gestion des exceptions permet de nettoyer une fois l'exception levée par l'activité, tandis que la compensation fournit un mécanisme permettant d'annuler un travail correctement terminé d'une activité précédemment terminée. Pour plus d’informations, consultez Compensation.