Agregar actividades en tiempo de ejecución a un flujo de trabajo

by Nicolás Ferreira 25. May 2008 00:00

Abrimos Visual Studio y creamos un nuevo proyecto de tipo Sequential Workflow Console Application al que llamaremos WorkflowSample2. Por defecto, Visual Studio nos deja en el diseñador visual de flujos de trabajo para Workflow1.cs. Si no es así, vamos al diseñador para Workflow1.cs. Agregamos las siguientes actividades:

- Tipo: CodeActivity – Nombre: codeActivity1 – Descripción: La vamos a utilizar para escribir la cadena "Actividad 1" a la salida de la consola.
- Tipo: SuspendActivity – Nombre: suspendActivity1 – Descripción: SuspendActivity suspende la ejecución de un flujo de trabajo. WorkflowRuntime levantará el evento WorkflowSuspended avisando que la instancia del flujo de trabajo ha entrado en estado de suspensión, lo que nos va a permitir hacer modificaciones al flujo de trabajo y luego resumir la ejecución.
- Tipo: SequenceActivity – Nombre: sequenceActivity1 – Descripción: SequenceActivity es una actividad compuesta que ejecuta actividades hijas en el orden en que fueron agregadas. En este caso, vamos a utilizarla como "placeholder" para agregar la nueva actividad.
- Tipo: CodeActivity – Nombre: codeActivity2 – Descripción: La vamos a utilizar para escribir la cadena "Actividad 3" a la salida de la consola.

Agregar actividades en tiempo de ejecución a un flujo de trabajo: Diseñador (Paso 1)

Hacemos clic derecho sobre codeActivity1 y seleccionamos la opción de menú "Generate Handlers" (que nos crea un nuevo manejador para el evento ExecuteCode). Volvemos al diseñador y repetimos el mismo paso pero para la actividad codeActivity2.

Agregar actividades en tiempo de ejecución a un flujo de trabajo: Diseñador (Paso 2)

Nos vamos a la vista de código y en los métodos generados (codeActivity1_ExecuteCode y codeActivity2_ExecuteCode) ponemos lo siguiente:

        private void codeActivity1_ExecuteCode(object sender, EventArgs e)
        {
            Console.WriteLine("Actividad 1");
        }

        private void codeActivity2_ExecuteCode(object sender, EventArgs e)
        {
            Console.WriteLine("Actividad 3");
        }

Hecho esto, agregamos una nueva clase al proyecto que llamaremos "EscribirMensajeActivity". Cambiamos la declaración de la clase para que sea pública y la hacemos heredar de Activity (System.Workflow.ComponentModel.Activity).

Activity es la clase base para todas las actividades. El método principal en el que ponemos la lógica de ejecución es Execute y es llamado por el runtime de flujos de trabajo.

Sobrescribimos entonces el método Execute y ponemos lo siguiente:

        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            Console.WriteLine(Mensaje);
            return ActivityExecutionStatus.Closed;
        }

Tenemos que crear un campo de tipo string llamado _Mensaje que va a servir como contenedor para la cadena que se va a escribir a la salida de la consola. Luego, creamos la propiedad para el campo _Mensaje.

        private string _Mensaje;

        public string Mensaje
        {
            get { return _Mensaje; }
            set { _Mensaje = value; }
        }

Por último vamos a hacer unas modificaciones al código que Visual Studio generó en Program.cs. Nos suscribimos al evento WorkflowSuspended de workflowRuntime:

        static void Main(string[] args)
        {
            using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())
            {
                AutoResetEvent waitHandle = new AutoResetEvent(false);
                workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { waitHandle.Set(); };
                workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
                {
                    Console.WriteLine(e.Exception.Message);
                    waitHandle.Set();
                };

                workflowRuntime.WorkflowSuspended +=
                    new EventHandler<WorkflowSuspendedEventArgs>(workflowRuntime_WorkflowSuspended);

            ...

En el método encargado de manejar el evento WorkflowSuspended (workflowRuntime_WorkflowSuspended) ponemos lo siguiente:

        static void workflowRuntime_WorkflowSuspended(object sender, WorkflowSuspendedEventArgs e)
        {
            WorkflowChanges lWorkflowChanges =
                new WorkflowChanges(e.WorkflowInstance.GetWorkflowDefinition());

            EscribirMensajeActivity lEscribirMensajeActivity = new EscribirMensajeActivity();
            lEscribirMensajeActivity.Mensaje = "Actividad 2";
            ((CompositeActivity)lWorkflowChanges.TransientWorkflow.Activities["sequenceActivity1"]).
                Activities.Add(lEscribirMensajeActivity);

            e.WorkflowInstance.ApplyWorkflowChanges(lWorkflowChanges);
            e.WorkflowInstance.Resume();
        }

Cuando queremos hacer cambios a un flujo de trabajo, los tenemos que hacer utilizando la clase WorkflowChanges que toma como parámetro la actividad raíz. En este caso la actividad raíz para la instancia del flujo de trabajo que queremos modificar la sacamos con el método GetWorkflowDefinition de WorkflowInstance que lo tenemos en "e" (WorkflowSuspendedEventArgs). Después, creamos una nueva instancia de nuestra actividad (EscribirMensajeActivity) y establecemos la propiedad Mensaje.

La propiedad TransientWorkflow de WorkflowChanges devuelve una copia exacta de la estructura del flujo de trabajo que vamos a utilizar para ubicar la actividad sequenceActivity1 que convertiremos a CompositeActivity para poder agregar la actividad hija.

Una vez agregada la actividad hija, llamamos al método ApplyWorkflowChanges de WorkflowInstance pasando la instancia de WorkflowChanges. Finalmente, llamamos al método Resume para continuar con la ejecución del flujo de trabajo.

Compilamos y ejecutamos. Deberíamos ver lo siguiente:

Agregar actividades en tiempo de ejecución a un flujo de trabajo

Tags:

.NET Development | Windows Workflow Foundation (WF)

Comments

7/11/2010 1:43:35 AM #

Lamar Conkrite

Thanks yet again for providing terrific content yet again. Definitely a pro-blogger if I�ve seen one particular.

Lamar Conkrite Republic of the Philippines | Reply

8/27/2010 9:57:23 AM #

nude cam

wat een dag wat een dag voor de eerste keer met een emmer water in een auto gezeten, dont try that at home want dat is geen succes!

nude cam United States | Reply

8/29/2010 10:59:42 PM #

Best Smokeless Cigarette

Thanks for the read, I will bookmark it and come back later to check out some of your other posts =)

Best Smokeless Cigarette United States | Reply

8/30/2010 9:22:33 PM #

Cleora Prigge

Going to see Kyau & Albert Tonight. Its gonna be amazing. There playing with Sebastian Ingrosso. Then next month ill be seeing Roger Shah. epic nights ahead

Cleora Prigge Ireland | Reply

8/31/2010 11:08:56 PM #

Lemonade Diet Recipe

This is very interesting. I actually enjoy your writing style and your word choice more than anything Smile

Lemonade Diet Recipe United States | Reply

9/1/2010 4:28:51 PM #

antique overmantle mirror

Thank you for the sensible critique. Me & my neighbour were preparing to do numerous research about that. We got a very good book on that matter from our regional library and also most books exactly where not as influensive as your information. I am incredibly glad to see such information that I was searching for a long time.That created incredibly glad Smile

antique overmantle mirror United States | Reply

Add comment


(Will show your Gravatar icon)

  Country flag

biuquote
  • Comment
  • Preview
Loading