Undantag för Windows Workflow Foundation

Arbetsflöden kan använda aktiviteten TryCatch för att hantera undantag som genereras under körningen av ett arbetsflöde. Dessa undantag kan hanteras eller så kan de genereras igen med hjälp av Rethrow-aktiviteten. Aktiviteter i avsnittet Finally körs när antingen avsnittet Try eller Catches har slutförts. Arbetsflöden som hanteras av en WorkflowApplication-instans kan också använda OnUnhandledException händelsehanterare för att hantera undantag som inte hanteras av en TryCatch aktivitet.

Orsaker till undantag

I ett arbetsflöde kan undantag genereras på följande sätt:

  • En timeout för transaktioner i TransactionScope.

  • Ett explicit undantag som genereras av arbetsflödet med hjälp av aktiviteten Throw.

  • Ett .NET Framework 4.6.1-undantag som genereras från en aktivitet.

  • Ett undantag som genereras från extern kod, till exempel bibliotek, komponenter eller tjänster som används i arbetsflödet.

Hantera undantag

Om ett undantag utlöses av en aktivitet och inte hanteras är standardbeteendet att avsluta arbetsflödesinstansen. Om det finns en anpassad OnUnhandledException-hanterare kan den åsidosätta det här standardbeteendet. Den här hanteraren ger upphovsmannen till arbetsflödet en möjlighet att tillhandahålla lämplig hantering, till exempel anpassad loggning, avbryta arbetsflödet, avbryta arbetsflödet eller avsluta arbetsflödet. Om ett arbetsflöde skapar ett undantag som inte hanteras anropas OnUnhandledException-hanteraren. Det finns tre möjliga åtgärder som returneras från OnUnhandledException som avgör det slutliga resultatet av arbetsflödet.

  • Avbryt – En instans av avbrutet arbetsflöde är en graciös avslutning av en grenkörning. Du kan modellera avbokningsbeteende (till exempel med hjälp av en CancellationScope-aktivitet). Hanteraren Slutförd anropas när annulleringsprocessen är klar. Ett avbrutet arbetsflöde är i tillståndet Avbrutet.

  • Avsluta – En avslutad arbetsflödesinstans kan inte återupptas eller startas om. Detta utlöser händelsen Slutförd där du kan ange ett undantag som orsak till att den avslutades. Den avslutade hanteraren anropas när avslutningsprocessen är klar. Ett avslutat arbetsflöde är i feltillstånd.

  • Avbryt – Instanser av avbrutna arbetsflöden kan bara återupptas om de har konfigurerats som beständiga. Utan beständighet kan inte ett arbetsflöde återupptas. När ett arbetsflöde avbryts går allt arbete som utförts (i minnet) sedan den senaste beständighetspunkten förlorade. För ett avbrutet arbetsflöde anropas den avbrutna hanteraren med undantaget som orsak när avbrottet slutförs. Men till skillnad från Avbrytd och Avslutad anropas inte den slutförda hanteraren. Ett avbrutet arbetsflöde är i ett avbrutet tillstånd.

I följande exempel anropas ett arbetsflöde som utlöser ett undantag. Undantaget hanteras inte av arbetsflödet och OnUnhandledException-hanteraren anropas. WorkflowApplicationUnhandledExceptionEventArgs inspekteras för att ange information om undantaget och arbetsflödet avslutas.

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 {e.InstanceId}\n{e.UnhandledException.Message}");

    Console.WriteLine($"ExceptionSource: {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();

Hantera undantag med TryCatch-aktiviteten

Hantering av undantag i ett arbetsflöde utförs med den TryCatch aktiviteten. Den TryCatch aktiviteten har en Catches samling Catch aktiviteter som var och en är associerade med en specifik Exception typ. Om undantaget som genereras av en aktivitet som finns i avsnittet Try i en TryCatch-aktivitet matchar undantaget för en Catch<TException> aktivitet i samlingen Catches hanteras undantaget. Om undantaget uttryckligen genereras på nytt eller om ett nytt undantag utlöses skickas det här undantaget till den överordnade aktiviteten. I följande kodexempel visas en TryCatch aktivitet som hanterar en ApplicationException som genereras i avsnittet Try av en Throw aktivitet. Undantagets meddelande skrivs till konsolen av Catch<TException>-aktiviteten och sedan skrivs ett meddelande till konsolen i avsnittet 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."
    }
};

Aktiviteterna i avsnittet Finally körs när antingen avsnittet Try eller Catches har slutförts. Avsnittet Try slutförs om inga undantag genereras från det, och Catches-avsnittet slutförs om inga undantag genereras eller återställs från det. Om ett undantag utlöses i avsnittet Try i en TryCatch och antingen inte hanteras av en Catch<TException> i avsnittet Catches, eller om de är inläst från Catches, kommer aktiviteterna i Finally inte att köras om inte något av följande inträffar.

Undantagshantering kontra kompensation

Skillnaden mellan undantagshantering och kompensation är att undantagshantering sker under körningen av en aktivitet. Kompensation inträffar när en aktivitet har slutförts. Undantagshantering ger möjlighet att rensa efter att aktiviteten har genererat undantaget, medan kompensation ger en mekanism genom vilken det slutförda arbetet för en tidigare slutförd aktivitet kan ångras. Mer information finns i Kompensation.

Se även