En este articulo profundizaremos un poco más acerca del Runtime Engine, los diferentes eventos del Runtime, su sintaxis y su uso en Workflow Foundation.
Runtime Engine
La arquitectura de Windows Workflow Foundation consta de seis partes principales, el Runtime Engine es una de ellas. El Runtime Engine es una librería que ejecuta flujos de trabajo. El Runtime Engine también provee otros servicios, como mecanismos para comunicarse con software fuera del flujo de trabajo. Todos los flujos de trabajos dependen del Windows Workflow Foundation Runtime Engine. Este motor ejecuta cada flujo de trabajo y maneja su estado a lo largo de su tiempo de vida. El Windows Workflow Foundation Runtime es una librería; por lo tanto, debe ser ejecutado en algún proceso host. En vez de proveer un host requerido, Windows Workflow Foundation le permite al Runtime (y a cualquier flujo de trabajo que ejecute) ser alojado en cualquier proceso Windows, desde una simple aplicación de consola de Windows o una aplicación de formulario, hasta un servidor complejo diseñado teniendo en cuenta el ambiente de flujo de trabajo.
Windows Workflow Foundation cuenta con un conjunto de servicios que le permiten al Runtime ejecutarse dentro de ASP.NET, aunque los vendedores independientes de software y los usuarios finales son libres de crear sus propias aplicaciones contenedoras de flujo de trabajos para aplicaciones existentes.
Al ser Windows Workflow Foundation un Framework para flujos de trabajo en vez de un producto independiente, y al soportar este tipo de diversidades, se convierte en una meta explícita para sus creadores. A pesar de que cada host usa el mismo Runtime Engine, cada uno debe proveer un conjunto de servicios Runtime. Estos servicios brindan soporte para persistir el estado de un flujo de trabajo, rastrear su ejecución, usar transacciones, etc.
Un flujo de trabajo puede ser de larga duración, ya que podría ejecutarse durante horas, días o semanas, y el Runtime de Windows Workflow Foundation podría apagarse durante un flujo de trabajo, y persistentemente almacenaría su estado si hubiera estado inactivo por un período de tiempo.
La decisión de descargar el flujo de trabajo se puede lanzar porque éste se encuentra bloqueado esperando un evento externo; esta decisión es tomada típicamente por el Runtime. Para escribir estados del flujo de trabajo en el disco, el Runtime depende del servicio de persistencia proporcionado por su proceso host.
Los eventos del flujo de trabajo son procesados por el Runtime a través de los delegados de manejo de eventos.

¿Por qué son importantes los Runtime Events?
Porque proporcionan un mecanismo para hacer un seguimiento del ciclo de vida del flujo de trabajo, por ejemplo cuando se crea un flujo de trabajo, cuando finaliza el mismo flujo, etc. Otro beneficio de manejar eventos del Runtime es que proporcionan un mecanismo para dar seguimiento a todas las instancias del flujo de trabajo. De esta forma podemos determinar cuántos fueron los flujos de trabajo fueron creados, abortados, terminados, etc. Entre los eventos que se ejecutan del lado del workflowRuntime a los que se puede suscribir son:
Del tipo:
Del motor:
De las instancias:
-
WorkflowCreated/Started/Stopped
-
WorkflowAborted/Terminated/Completed
-
WorkflowIdled/Loaded/Persisted/Unloaded
Eventos de Flujo de Trabajo
Los eventos del flujo de trabajo son procesados por el Runtime a través de los delegados de manejo de eventos. Estos eventos son generados/levantados por el Runtime del flujo de trabajo y no por la instancia del flujo de trabajo. Asimismo, tampoco son modelados como parte de la definición de flujo de trabajo. Los eventos enviados por el Runtime del flujo de trabajo contiene el identificador de la instancia del flujo de trabajo que generó el evento. La Tabla 1 nos muestra los diferentes eventos de flujo de trabajo existentes:
| Eventos de flujo de trabajo | Descripción |
| ServicesExceptionNotHandled | Generado cuando la instancia del flujo de trabajo no puede manejar la excepción interna |
| Started | Generado cuando se inicia el runtime |
| Stopped | Generado cuando se detiene el runtime |
| WorkflowAborted | Generado cuando se aborta la instancia del flujo de trabajo |
| WorkflowCompleted | Generado cuando se completa la instancia del flujo de trabajo |
| WorkflowCreated | Generado cuando se crea la instancia del flujo de trabajo |
| WorkflowIdled | Generado cuando la instancia del flujo de trabajo está inactiva(por ejemplo: Delay o EventSink) |
| WorkflowLoaded | Generado cuando la instancia del flujo de trabajo se carga en memoria (por ejemplo: re-hydrated) |
| WorkflowPersisted | Generado cuando la instancia del flujo de trabajo tiene persistencia |
| WorkflowResumed | Generado cuando la instancia del flujo de trabajo se reanuda después de ser suspendida |
| WorkflowStarted | Generado cuando se inicia la instancia del flujo de trabajo |
| WorkflowSuspended | Generado cuando el runtime suspende la instancia del flujo de trabajo |
| WorkflowTerminated | Generado cuando el runtime o internamente se termina la instancia del flujo de trabajo |
| WorkflowUnloaded | Generado cuando la instancia del flujo de trabajo se descarga de memoria (por ejemplo: Hydrated) |
Tabla 1. Eventos de Flujo de Trabajo
En el siguiente ejemplo podemos ver la implementación del evento WorkflowCompleted del WorkFlowRuntime:
private void ApplicationInitMethod()
{
WorkflowRuntime workflowRuntime = new WorkflowRuntime();
workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(
workflowRuntime_WorkflowCompleted);
}
void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
{
MessageBox.Show("Se completó el flujo de trabajo");
}
En el siguiente ejemplo podemos ver la implementación del evento WorkflowCreated del WorkFlowRuntime:
private void ApplicationInitMethod()
{
WorkflowRuntime workflowRuntime = new WorkflowRuntime();
workflowRuntime.WorkflowCreated += new EventHandler<WorkflowCompletedEventArgs>(
workflowRuntime_WorkflowCreated);
}
void workflowRuntime_WorkflowCreated(object sender, WorkflowCompletedEventArgs e)
{
MessageBox.Show("Se creó el flujo de trabajo");
}