Eccezioni di Windows Workflow Foundation

I flussi di lavoro possono usare l'attività TryCatch per gestire le eccezioni generate durante l'esecuzione di un flusso di lavoro. Queste eccezioni possono essere gestite o generate una seconda volta usando l'attività Rethrow. Le attività della sezione Finally vengono eseguite quando viene completata la sezione Try o Catches. I flussi di lavoro ospitati da un'istanza WorkflowApplication possono anche usare il OnUnhandledException gestore eventi per gestire le eccezioni che non vengono gestite da un'attività TryCatch .

Cause delle eccezioni

In un flusso di lavoro le eccezioni possono essere generate con le modalità seguenti:

  • Timeout delle transazioni nell'oggetto TransactionScope.

  • Eccezione esplicita generata dal flusso di lavoro usando l'attività Throw.

  • Eccezione di .NET Framework 4.6.1 generata da un'attività.

  • Eccezione generata da codice esterno, ad esempio librerie, componenti o servizi usati nel flusso di lavoro.

Gestione delle eccezioni

Se un'eccezione viene generata da un'attività ma non viene gestita, il comportamento predefinito prevede l'interruzione dell'istanza del flusso di lavoro. Se presente, un gestore personalizzato OnUnhandledException può eseguire l'override di questo comportamento predefinito. Questo gestore consente all'autore dell'host del flusso di lavoro di fornire la gestione appropriata, ad esempio la registrazione personalizzata, l'interruzione, l'annullamento o la chiusura del flusso di lavoro. Se un flusso di lavoro genera un'eccezione che non viene gestita, viene chiamato il gestore OnUnhandledException. Esistono tre azioni possibili restituite da OnUnhandledException che determinano il risultato finale del flusso di lavoro.

  • Annulla : un'istanza del flusso di lavoro annullata è un'uscita graziata di un'esecuzione di ramo. È possibile modellare il comportamento di annullamento, ad esempio usando un'attività CancellationScope. Il gestore Completed viene richiamato al completamento del processo di annullamento. Un flusso di lavoro annullato si trova nello stato di annullato.

  • Termina : non è possibile riprendere o riavviare un'istanza del flusso di lavoro terminata. Ciò attiva l'evento Completed in cui è possibile immettere un'eccezione come motivo del termine dell'istanza. Il gestore Terminated viene richiamato al completamento del processo di chiusura. Un flusso di lavoro terminato si trova nello stato di non riuscito.

  • Interruzione : è possibile riprendere istanze del flusso di lavoro interrotte solo se è stata configurata per essere persistente. Senza la persistenza, un flusso di lavoro non può essere ripreso. Nel momento in cui un flusso di lavoro viene interrotto, qualsiasi lavoro eseguito (in memoria) dall'ultimo di punto di persistenza verrà perso. Per un flusso di lavoro interrotto, viene richiamato il gestore Aborted usando l'eccezione come motivo di quando è stato completato il processo di interruzione. Tuttavia, a differenza dei gestori Cancelled e Terminated, il gestore Completed non viene richiamato. Un flusso di lavoro interrotto si trova nello stato di interrotto.

Nell'esempio seguente viene richiamato un flusso di lavoro che genera un'eccezione. L'eccezione non viene gestita dal flusso di lavoro e viene richiamato il gestore OnUnhandledException. Gli argomenti WorkflowApplicationUnhandledExceptionEventArgs vengono controllati per fornire informazioni sull'eccezione e il flusso di lavoro viene terminato.

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

Gestione delle eccezioni con l'attività TryCatch

La gestione delle eccezioni in un flusso di lavoro viene eseguita con l'attività TryCatch. L'attività TryCatch dispone di una raccolta Catches di attività Catch, ognuna delle quali è associata a un tipo Exception specifico. Se l'eccezione generata da un'attività contenuta nella sezione Try di un'attività TryCatch corrisponde all'eccezione di un'attività Catch<TException> nella raccolta Catches, l'eccezione viene gestita. Se l'eccezione viene generata in modo esplicito una seconda volta oppure viene generata una nuova eccezione, quest'ultima passa fino all'attività padre. Nell'esempio di codice seguente viene mostrata un'attività TryCatch che gestisce un oggetto ApplicationException generato nella sezione Try da un'attività Throw. Il messaggio dell'eccezione viene scritto nella console dall'attività Catch<TException>, quindi viene scritto un messaggio nella console nella sezione 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."
    }
};

Le attività della sezione Finally vengono eseguite quando viene completata correttamente la sezione Try o Catches. La sezione Try viene completata correttamente se non vengono generate eccezioni dal suo interno e la sezione Catches viene completata correttamente se non viene generata o rigenerata alcuna eccezione dal suo interno. Se un'eccezione viene generata nella sezione Try section di TryCatch e o non è gestita da un oggetto Catch<TException> nella sezione Catches o è rigenerata dall'oggetto Catches, le attività in Finally non verranno eseguite a meno che non si verifichi una delle situazioni indicate di seguito.

Gestione delle eccezioni e compensazione

La gestione delle eccezioni si verifica durante l'esecuzione di un'attività, mentre la compensazione si verifica dopo il corretto completamento di un'attività. La gestione delle eccezioni consente di eseguire una pulizia dopo che l'attività genera l'eccezione, mentre la compensazione permette di annullare il lavoro correttamente completato di un'attività portata a termine in precedenza. Per altre informazioni, vedere Compensazione.

Vedere anche