Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los flujos de trabajo pueden usar la actividad de TryCatch para controlar las excepciones que se generan durante la ejecución de un flujo de trabajo. Estas excepciones se pueden controlar o se pueden volver a iniciar mediante la actividad Rethrow. Las actividades de la sección Finally se ejecutan cuando se completa la sección Try o la sección Catches. Los flujos de trabajo hospedados por una instancia de WorkflowApplication también pueden usar el controlador de eventos OnUnhandledException para controlar las excepciones que no se controlan mediante una actividad de TryCatch.
Causas de excepciones
En un flujo de trabajo, se pueden generar excepciones de las maneras siguientes:
Tiempo de espera de las transacciones en TransactionScope.
Excepción explícita producida por el flujo de trabajo mediante la actividad Throw.
Excepción de .NET Framework 4.6.1 producida desde una actividad.
Excepción producida desde código externo, como bibliotecas, componentes o servicios que se usan en el flujo de trabajo.
Controlar las excepciones
Si una actividad produce una excepción y no está controlada, el comportamiento predeterminado es finalizar la instancia de flujo de trabajo. Si existe un controlador de OnUnhandledException personalizado, puede invalidar este comportamiento predeterminado. Este controlador ofrece al autor del host de flujo de trabajo una oportunidad para proporcionar el control adecuado, como el registro personalizado, la anulación del flujo de trabajo, la cancelación del flujo de trabajo o la finalización del flujo de trabajo. Si un flujo de trabajo genera una excepción que no se controla, se invoca el controlador de OnUnhandledException. Hay tres acciones posibles devueltas de OnUnhandledException que determinan el resultado final del flujo de trabajo.
Cancelar: una instancia de flujo de trabajo cancelada es una salida correcta de una ejecución de rama. Puede modelar el comportamiento de cancelación (por ejemplo, mediante una actividad CancellationScope). El controlador Completed se invoca cuando se completa el proceso de cancelación. Un flujo de trabajo cancelado está en estado Cancelado.
Finalizar: no se puede reanudar ni reiniciar una instancia de flujo de trabajo terminada. Esto desencadena el evento Completed en el que puede proporcionar una excepción como motivo por el que se finalizó. El controlador Terminado se invoca cuando se completa el proceso de terminación. Un flujo de trabajo terminado está en estado De error.
Anular: solo se pueden reanudar instancias de flujo de trabajo anuladas si se ha configurado para que sea persistente. Sin persistencia, no se puede reanudar un flujo de trabajo. En el momento en que se anula un flujo de trabajo, se perderá cualquier trabajo realizado (en memoria) desde el último punto de persistencia. Para un flujo de trabajo anulado, el controlador anulado se invoca mediante la excepción como motivo cuando se completa el proceso de anulación. Sin embargo, a diferencia de Canceled y Terminated, no se invoca el controlador Completed. Un flujo de trabajo anulado está en estado Anulado.
En el ejemplo siguiente se invoca un flujo de trabajo que produce una excepción. El flujo de trabajo no controla la excepción y se invoca al controlador de OnUnhandledException. El WorkflowApplicationUnhandledExceptionEventArgs se inspecciona para proporcionar información sobre la excepción y se finaliza el flujo de trabajo.
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();
Control de excepciones con la actividad TryCatch
El control de excepciones dentro de un flujo de trabajo se realiza con la actividad TryCatch. La actividad TryCatch tiene una colección Catches de Catch actividades que están asociadas a un tipo de Exception específico. Si la excepción producida por una actividad contenida en la sección Try de una actividad de TryCatch coincide con la excepción de una actividad de Catch<TException> en la colección Catches, se controla la excepción. Si la excepción se vuelve a producir explícitamente o se produce una nueva excepción, esta excepción pasa a la actividad primaria. En el ejemplo de código siguiente se muestra una actividad de TryCatch que controla un ApplicationException que se produce en la sección Try mediante una actividad de Throw. La actividad de Catch<TException> escribe el mensaje de la excepción en la consola y, a continuación, se escribe un mensaje en la consola en la sección 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."
}
};
Las actividades de la sección Finally se ejecutan cuando la sección Try o la sección Catches se completan correctamente. La sección Try se completa correctamente si no se inicia ninguna excepción desde ella y la sección Catches se completa correctamente si no se produce ninguna excepción o se vuelve a iniciar desde ella. Si se produce una excepción en la sección Try de un TryCatch y no se controla mediante un Catch<TException> en la sección Catches o se vuelve a iniciar desde el Catches, las actividades de la Finally no se ejecutarán a menos que se produzca la siguiente excepción.
La excepción se detecta mediante una actividad de nivel superior TryCatch en el flujo de trabajo, independientemente de si se vuelve a iniciar desde ese nivel superior TryCatch.
La excepción no se controla mediante un nivel superior TryCatch, escapa a la raíz del flujo de trabajo y el flujo de trabajo está configurado para cancelar en lugar de finalizar o anular. Los flujos de trabajo hospedados mediante WorkflowApplication pueden configurarlo controlando OnUnhandledException y devolviendo Cancel. En este tema se proporciona un ejemplo de control de OnUnhandledException. Los servicios de flujo de trabajo pueden configurarlo mediante WorkflowUnhandledExceptionBehavior y especificando Cancel. Para obtener un ejemplo de configuración de WorkflowUnhandledExceptionBehavior, consulte la extensibilidad del host del servicio de flujo de trabajo.
Control de excepciones frente a compensación
La diferencia entre el control de excepciones y la compensación es que el control de excepciones se produce durante la ejecución de una actividad. La compensación se produce después de que una actividad se haya completado correctamente. El control de excepciones proporciona una oportunidad para limpiar después de que la actividad genere la excepción, mientras que la compensación proporciona un mecanismo por el que se puede deshacer el trabajo completado correctamente de una actividad completada previamente. Para obtener más información, consulte Compensación.