Compartir a través de


Tarea 2: Creación de un cliente de servicio de flujo de trabajo

En esta tarea, crea un cliente de servicio de flujo de trabajo básico que invoca las operaciones definidas e implementadas en el servicio de flujo de trabajo que creó en Tarea 1: Creación del servicio de flujo de trabajo. El cliente muestra en una ventana de la consola qué valor pasó en cada invocación de operación matemática y lo que el servicio devolvió como respuesta.

Nota

Este cliente se usa en los ejercicios restantes de este tutorial.

Nota

Cuando se usa el diseñador de flujo de trabajo de Visual Studio para crear o administrar servicios de flujo de trabajo, a veces se generan errores de validación falsos. Si puede generar correctamente su proyecto, omita los errores de validación.

Para crear el cliente de servicio de flujo de trabajo

  1. Si no tiene abierta la solución WorkflowServiceTutorial, abra Visual Studio 2008, haga clic en Archivo, resalte Abrir y vaya a la solución WorkflowServiceTutorial.

  2. Si WcfSvcHost.exe no se está ejecutando, presione Ctrl + F5 para generar y ejecutar el servicio de WorkflowServiceTutorial. Este servicio se debe estar ejecutando para completar los pasos de esta tarea. Haga clic con el botón secundario en WorkflowServiceTutorial.ServerWorkflow en la lista Servicio y elija Copiar dirección de metadatos.

  3. Haga clic en Archivo, resalte Agregar y seleccione Nuevo proyecto.

  4. En el cuadro de diálogo Nuevo proyecto, en Flujo de trabajo, seleccione Aplicación de consola de flujos de trabajo secuenciales.

  5. Asigne un nombre a su proyecto WorkflowServiceClient y haga clic en Aceptar.

  6. Haga clic con el botón secundario en el nodo WorkflowServiceClient en el Explorador de soluciones y elija Agregar referencia de servicio...

    Pegue la dirección de metadatos que copió en un paso anterior en el cuadro Dirección del cuadro de diálogo Agregar referencia de servicio y haga clic en Ir. Una vez que ServerWorkflow aparezca en el cuadro Servicios, haga clic en Aceptar para agregar la referencia del servicio.

  7. Abra la página de Workflow Designer para su flujo de trabajo y agregue una actividad SendActivity a su flujo de trabajo utilizando el panel Cuadro de herramientas.

  8. Resalte la actividad SendActivity en Workflow Designer.

  9. Desplácese al panel Propiedades y bajo la propiedad ServiceOperationInfo, haga clic en los puntos suspensivos para abrir el cuadro de diálogo Seleccionar operación.

  10. En la esquina superior derecha, haga clic en Importar.

  11. En la ficha Tipo, resalte <Proyecto actual>.

  12. Seleccione IWorkflow1 en la lista de tipos y haga clic en Aceptar.

    El cuadro de diálogo Seleccionar operación se rellenará con información sobre el contrato y la operación definida por la plantilla e implementada por usted en el proyecto WorkflowServiceTutorial.

  13. En Operaciones disponibles, resalte StartupService y haga clic en Aceptar.

    El diseñador asocia la actividad SendActivity a la operación de StartupService creando un objeto TypedOperationInfo, rellenándolo con información de contrato y operación, y asociándolo a su actividad SendActivity a través de la propiedad ServiceOperationInfo.

  14. En Workflow Designer, desplácese al panel Propiedades.

  15. En la propiedad ChannelToken, cree un nombre para el objeto ChannelToken y presione ENTRAR.

  16. Establece la propiedad ChannelToken.

  17. Para la propiedad EndpointName, navegue al archivo App.config para el cliente. Copie y pegue el nombre para el extremo que desea utilizar para tener acceso al servicio. Por ejemplo, en el código siguiente, el nombre de extremo es "WSHttpContextBinding_IWorkflow1."

    <client>
        <endpoint address="https://localhost:8080/ServerWorkflow" binding="wsHttpContextBinding"
            bindingConfiguration="WSHttpContextBinding_IWorkflow1" contract="ServiceReference.IWorkflow1"
            name="WSHttpContextBinding_IWorkflow1">
            <identity>
                <userPrincipalName value="someone@example.com" />
            </identity>
        </endpoint>
    </client>
    

    Nota

    La propiedad EndpointName y el atributo de nombre en su archivo App.config deben ser iguales o recibirá errores al ejecutar su aplicación cliente.

  18. Para la propiedad OwnerActivityName, deje el espacio en blanco. Si no selecciona un nombre, el nombre de la actividad raíz estará seleccionado durante el tiempo de compilación.

  19. En el panel Propiedades, haga clic en el botón Eventos.

  20. Haga doble clic en el cuadro de texto para que el evento AfterResponse genere un controlador de eventos.

  21. Escriba el código siguiente para mostrar el mensaje siguiente al usuario una vez invocada la operación StartupService.

    Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("A service instance has successfully been created.")
        End Sub
    
    private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
    {
        Console.WriteLine("A service instance has successfully been created.");
    }
    
  22. En Workflow Designer, agregue cinco actividades SendActivity más.

  23. Asocie cada actividad SendActivity a una operación y el mismo token del canal de cliente que utilizó en los pasos 13-17.

  24. Dado que las operaciones de matemática (Sumar, Restar, Multiplicar, Dividir) toman un int denominado n1, debe crear un enlace de actividad para n1 o establecer un valor para él. En este tutorial, enlazaremos con una propiedad existente en nuestro flujo de trabajo. Para ello, abra Workflow1.cs (o Workflow1.vb si creó una solución de Visual Basic) y realice los pasos siguientes:

    1. Cambie el nombre de la clase Workflow1 a ClientWorkflow.

    2. En su definición de claseClientWorkflow, cree una propiedad pública como se muestra en el ejemplo siguiente:

      Public class ClientWorkflow
          Inherits SequentialWorkflowActivity
      
          Public inputValue As Integer = Nothing
      
          Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
              Console.WriteLine("A service instance has successfully been created.")
          End Sub
      End Class
      
      public sealed partial class ClientWorkflow: SequentialWorkflowActivity
      {
          public int inputValue = default(int);
      
          public ClientWorkflow()
          {
              InitializeComponent();
          }
      
          private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
          {
              Console.WriteLine("A service instance has successfully been created.");
          }
      }
      
    3. Abra el diseñador de flujo de trabajo, y en el panel Propiedades para la actividad SendActivity asociada a la invocación de la operación Agregar, enlace inputValue a la propiedad de actividad n1 haciendo clic en los puntos suspensivos y seleccionando inputValue en la ficha Enlazar a un miembro existente.

    4. Implemente un controlador de eventos para que el evento BeforeSend cree el mensaje que se enviará al servicio.

      Private Sub sendActivity2_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
          inputValue = 1
          Console.WriteLine("The initial input value is {0}", inputValue)
      End Sub
      
      private void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e)
      {
          inputValue = 1;
          Console.WriteLine("The initial input value is {0}", inputValue);
      }
      
  25. Para mostrar los resultados del servicio, necesita crear una variable que contenga el valor que se devuelve cuando la operación tiene éxito. Para ello, abra Workflow1.cs (o Workflow1.vb si creó una solución de Visual Basic) y realice los pasos siguientes:

    1. En su definición de clase ClientWorkflow, cree una propiedad pública denominada returnedValue como se muestra en el ejemplo siguiente.

      Public class ClientWorkflow
          Inherits SequentialWorkflowActivity
      
          Public inputValue As Integer = Nothing
          Public returnedValue As Integer = Nothing
      ...
      End Class
      
      public sealed partial class ClientWorkflow: SequentialWorkflowActivity
      {
          public int inputValue = default(int);
          public int returnedValue = default(int);
      
          public ClientWorkflow()
          {
              InitializeComponent();
          }
      ...
      }
      
    2. Abra el diseñador de flujo de trabajo, y en el panel Propiedades, enlace returnedValue a la propiedad de actividad (ReturnValue) haciendo clic en los puntos suspensivos y seleccionando returnedValue en la ficha Enlazar a un miembro existente.

    3. Implemente un controlador de eventos para que el evento AfterResponse vea el mensaje devuelto por el servicio.

      private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e)
      {
          Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue); 
      }
      
  26. Para cada una de las demás operaciones matemáticas, enlace inputValue y returnedValue a n1 y (ReturnValue), respectivamente.

  27. Implemente controladores de eventos para los eventos BeforeSend y AfterResponse en cada actividad SendActivity restante asociada a una operación matemática como hizo en los pasos 24c y 25c. El siguiente ejemplo muestra la implementación de todos los controladores de eventos, incluido el de la actividad SendActivity asociada a la operación ShutdownService.

        Private Sub sendActivity1_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("A service instance has successfully been created.")
        End Sub
    
        Private Sub sendActivity2_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 1
            Console.WriteLine("The initial input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity2_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity3_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 2
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity3_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Subtract operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity4_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 6
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity4_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Multiply operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity5_BeforeSend(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            inputValue = 3
            Console.WriteLine("The new input value is {0}", inputValue)
        End Sub
    
        Private Sub sendActivity5_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The value after invoking the Divide operation is {0}", returnedValue)
        End Sub
    
        Private Sub sendActivity6_AfterResponse(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.SendActivityEventArgs)
            Console.WriteLine("The workflow service instance has been successfully shut down.")
        End Sub
    
        private void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("A service instance has successfully been created.");
        }
    
        private void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 1;
            Console.WriteLine("The initial input value is {0}", inputValue);
        }
    
        private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue);
        }
    
        private void sendActivity3_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 2;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity3_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Subtract operation is {0}", returnedValue);
        }
    
        private void sendActivity4_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 6;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity4_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Multiply operation is {0}", returnedValue);
        }
    
        private void sendActivity5_BeforeSend(object sender, SendActivityEventArgs e)
        {
            inputValue = 3;
            Console.WriteLine("The new input value is {0}", inputValue);
        }
    
        private void sendActivity5_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The value after invoking the Divide operation is {0}", returnedValue);
        }
    
        private void sendActivity6_AfterResponse(object sender, SendActivityEventArgs e)
        {
            Console.WriteLine("The workflow service instance has been successfully shut down.");
        }
    
  28. En Program.cs (o Module1.vb en Visual Basic), agregue ChannelManagerService a la lista de servicios utilizada por WorkflowRuntime para almacenar en memoria caché canales y generadores de canales. Utilizar ChannelManagerService es opcional, pero si no lo utiliza, los canales no se almacenarán en memoria caché y cada actividad SendActivity en un flujo de trabajo utilizará una nueva instancia de canal cuando se comunique con el servicio.

    Shared WaitHandle As New AutoResetEvent(False)
    
    Shared Sub Main()
        Using workflowRuntime As New WorkflowRuntime()
            AddHandler workflowRuntime.WorkflowCompleted, AddressOf OnWorkflowCompleted
            AddHandler workflowRuntime.WorkflowTerminated, AddressOf OnWorkflowTerminated
    
            ' Add ChannelManagerService to the list of services used by the WorkflowRuntime.
            Dim cms As ChannelManagerService = New ChannelManagerService()workflowRuntime.AddService(cms)
    
            Dim workflowInstance As WorkflowInstance
            workflowInstance = workflowRuntime.CreateWorkflow(GetType(ClientWorkflow))
            workflowInstance.Start()
            WaitHandle.WaitOne()
        End Using
    End Sub
    Shared Sub OnWorkflowCompleted(ByVal sender As Object, ByVal e As WorkflowCompletedEventArgs)
        Console.WriteLine("The client workflow has completed." + vbLf + "Press <Enter> to exit the client application.")
        Console.ReadLine()
        WaitHandle.Set()
    End Sub
    
    Shared Sub OnWorkflowTerminated(ByVal sender As Object, ByVal e As WorkflowTerminatedEventArgs)
        Console.WriteLine(e.Exception.Message)
        WaitHandle.Set()
    End Sub
    
    using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
    {
        AutoResetEvent waitHandle = new AutoResetEvent(false);
    
        // Add ChannelManagerService to the list of services used 
        // by the WorkflowRuntime.
        ChannelManagerService cms = new ChannelManagerService();    workflowRuntime.AddService(cms);
    
        workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) 
        {
            Console.WriteLine("The client workflow has completed. \nPress <Enter> to exit the client application."); 
            Console.ReadLine(); 
            waitHandle.Set(); 
        };
    
        workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
        {
            Console.WriteLine(e.Exception.Message);
            waitHandle.Set();
        };
    
        WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowServiceClient.ClientWorkflow));
        instance.Start();
    
        waitHandle.WaitOne();
    }
    
  29. Para utilizar el cliente con su servicio de flujo de trabajo en la solución WorkflowServiceTutorial creada en el ejercicio 1, debe eliminar un argumento de la línea de comandos de las propiedades de proyecto de WorkflowServiceTutorial. Para ello, realice los pasos siguientes:

    1. Haga clic con el botón secundario en el nodo de proyecto de WorkflowServiceTutorial y seleccione Propiedades.
    2. Seleccione la ficha Depurar y en el panel de detalles de Opciones de inicio, elimine /cliente: "WfcTestClient.exe" del cuadro de texto.
  30. Haga clic con el botón secundario en el nodo de solución de WorkflowServiceTutorial y seleccione Propiedades.

  31. En el cuadro de diálogo de páginas de propiedades, seleccione la opción Proyectos de inicio múltiples.

  32. Si WorkflowServiceTutorial no aparece como el elemento superior de la lista, utilice las flechas situadas junto a la lista para convertirlo en el elemento superior. Esto es necesario para que su servicio empiece a ejecutarse antes de que su aplicación cliente intente invocar cualquier operación en el servicio.

  33. Para cada proyecto de la lista, cambie la acción de Ninguno a Inicio.

  34. Haga clic en Aplicar y luego en Aceptar.

  35. Si ha creado una solución de Visual Basic, entonces en el panel Explorador de soluciones, haga clic con el botón secundario en el nodo de proyecto de WorkflowServiceClient y seleccione Propiedades.

  36. Seleccione la ficha Aplicación y elimine WorkflowServiceClient del cuadro de texto Espacio de nombres Raíz. Si no hace esto, a continuación, no podrá conectarse al servicio de flujo de trabajo porque el cliente estará haciendo referencia al espacio de nombres equivocado.

  37. Genere y ejecute la solución de servicio de flujo de trabajo.

  38. Después de que se inicie el servicio, se ejecuta la aplicación cliente. Debería observar lo siguiente al ejecutar su aplicación cliente desde el símbolo del sistema.

    A workflow service instance has successfully been created.
    The initial input value is 1
    The value after invoking the Add operation is 1
    The new input value is 2
    The value after invoking the Subract operation is -1
    The new input value is 6
    The value after invoking the Multiply operation is -6
    The new input value is 3
    The value after invoking the Divide operation is -2
    The workflow service instance has been successfully shut down.
    The client workflow has completed. 
    Press <Enter> to exit the client application.
    

Consulte también

Otros recursos

Ejercicio 1: Creación de un servicio de flujo de trabajo básico

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.