Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Im Rahmen dieser Aufgabe erstellen Sie einen einfachen Workflowdienstclient, von dem die Vorgänge aufgerufen werden, die im unter Aufgabe 1: Erstellen des Workflowdiensts erstellten Workflowdienst definiert und implementiert sind. In einem Konsolenfenster wird vom Client angezeigt, welcher Wert in die einzelnen mathematischen Vorgangsaufrufe eingegeben wurde und was vom Dienst als Antwort zurückgesendet wurde.
Tipp
Dieser Client wird in den verbleibenden Übungen dieses Lernprogramms verwendet.
Tipp
Wird der Workflow-Designer von Visual Studio zum Erstellen oder Verwalten von Workflowdiensten verwendet, werden dadurch gelegentlich unechte Validierungsfehler verursacht. Falls Sie das Projekt erfolgreich erstellen können, ignorieren Sie die Auswertungsfehler.
So erstellen Sie einen Workflowdienstclient:
Falls Sie derzeit über keine offene WorkflowServiceTutorial-Lösung verfügen, öffnen Sie Visual Studio 2008, klicken Sie auf Datei, markieren Sie Öffnen, und navigieren Sie zur WorkflowServiceTutorial-Lösung.
Wenn WcfSvcHost.exe nicht ausgeführt wird, drücken Sie STRG+F5, um den WorkflowServiceTutorial-Dienst zu erstellen und auszuführen. Dieser Dienst muss für die Schritte in dieser Aufgabe ausgeführt werden. Klicken Sie in der Liste Dienst mit der rechten Maustaste auf WorkflowServiceTutorial.ServerWorkflow, und wählen Sie Metadatenadresse kopieren aus.
Klicken Sie auf Datei, markieren Sie Hinzufügen, und wählen Sie Neues Projekt aus.
Wählen Sie im Dialogfeld Neues Projekt unter Workflow die Option Konsolenanwendung für sequenzielle Workflows aus.
Geben Sie für das Projekt den Namen WorkflowServiceClient ein, und klicken Sie auf OK.
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten WorkflowServiceClient, und wählen Sie Dienstverweis hinzufügen aus.
Fügen Sie die im vorhergehenden Schritt kopierte Metadatenadresse in das Feld Adresse des Dialogfelds Dienstverweis hinzufügen ein, und klicken Sie auf Gehe zu. Sobald ServerWorkflow im Feld Dienste angezeigt wird, klicken Sie auf OK, um den Dienstverweis hinzuzufügen.
Öffnen Sie die Workflow-Designer-Seite für Ihren Workflow, und fügen Sie dem Workflow mithilfe des Bereichs Toolbox eine SendActivity-Aktivität hinzu.
Markieren Sie die SendActivity-Aktivität im Workflow-Designer.
Navigieren Sie zum Bereich Eigenschaften, und klicken Sie unter der ServiceOperationInfo-Eigenschaft auf die Auslassungszeichen, um das Dialogfeld Vorgang auswählen zu öffnen.
Klicken Sie rechts oben auf Importieren.
Markieren Sie auf der Registerkarte Typ die Option <Aktuelles Projekt>.
Wählen Sie in der Typliste IWorkflow1 aus, und klicken Sie auf OK.
Das Dialogfeld Vorgang auswählen wird mit Informationen zum Vertrag und dem Vorgang ausgefüllt, der in der Vorlage definiert ist und von Ihnen in das WorkflowServiceTutorial-Projekt implementiert wurde.
Markieren Sie unter Verfügbare Vorgänge die Option StartupService, und klicken Sie auf OK.
Die SendActivity-Aktivität wird vom Designer dem
StartupService-Vorgang zugeordnet, indem ein TypedOperationInfo-Objekt erstellt, mit Vertrags- und Vorgangsinformationen ausgefüllt und der SendActivity-Aktivität über die ServiceOperationInfo-Eigenschaft zugeordnet wird.Navigieren Sie im Workflow-Designer zum Bereich Eigenschaften.
Erstellen Sie in der ChannelToken-Eigenschaft einen Namen für das ChannelToken-Objekt, und drücken Sie die EINGABETASTE.
Erweitern Sie die ChannelToken-Eigenschaft.
Navigieren Sie zur Datei App.config für den Client, um die EndpointName-Eigenschaft zu erhalten. Kopieren Sie den Namen für den Endpunkt, den Sie zum Zugriff auf den Dienst verwenden möchten, und fügen Sie ihn ein. Im folgenden Code lautet der Endpunktname z. B. "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>Tipp
Die EndpointName-Eigenschaft und das Name-Attribut in der Datei App.config müssen übereinstimmen. Andernfalls erhalten Sie beim Ausführen der Clientanwendung Fehler.
Lassen Sie dieses Feld für die OwnerActivityName-Eigenschaft leer. Wählen Sie keinen Namen aus, wird zur Kompilierungszeit der Name der Stammaktivität für Sie ausgewählt.
Klicken Sie im Bereich Eigenschaften auf die Schaltfläche Ereignisse.
Doppelklicken Sie im Textfeld für das AfterResponse-Ereignis, um einen Ereignishandler zu generieren.
Geben Sie folgenden Code ein, um dem Benutzer folgende Nachricht anzuzeigen, nachdem der StartupService-Vorgang aufgerufen wurde.
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 Subprivate void sendActivity1_AfterResponse(object sender, SendActivityEventArgs e) { Console.WriteLine("A service instance has successfully been created."); }Fügen Sie im Workflow-Designer fünf weitere SendActivity-Aktivitäten hinzu.
Ordnen Sie jeder SendActivity-Aktivität einen Vorgang und denselben Clientkanaltoken wie in den Schritten 13-17 zu.
Da für mathematische Operationen (Addieren, Subtrahieren, Multiplizieren, Dividieren) ein int mit der Bezeichnung n1 verwendet wird, muss entweder eine Aktivitätsbindung für n1 erstellt oder ein Wert dafür festgelegt werden. In diesem Lernprogramm wird in unserem Workflow eine Bindung an eine vorhandene Eigenschaft erstellt. Öffnen Sie hierzu Workflow1.cs (oder Workflow1.vb, falls Sie eine Visual Basic-Projektmappe erstellt haben), und führen Sie die folgenden Schritte aus:
Benennen Sie die Workflow1-Klasse in ClientWorkflow um.
Erstellen Sie in der
ClientWorkflow-Klassendefinition wie im folgenden Beispiel gezeigt eine öffentliche Eigenschaft: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 Classpublic 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."); } }Öffnen Sie den Workflow-Designer, und binden Sie im Bereich Eigenschaften für die SendActivity-Aktivität, die dem Aufrufen des Vorgangs Hinzufügen zugeordnet ist, inputValue an die n1-Aktivitätseigenschaft. Klicken Sie dazu auf die Schaltfläche mit den Auslassungszeichen, und wählen Sie auf der Registerkarte Binden an einen vorhandenen Member die Option inputValue aus.
Implementieren Sie einen Ereignishandler für das BeforeSend-Ereignis, um die an den Dienst zu sendende Nachricht zu erstellen.
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 Subprivate void sendActivity2_BeforeSend(object sender, SendActivityEventArgs e) { inputValue = 1; Console.WriteLine("The initial input value is {0}", inputValue); }
Zum Anzeigen der vom Dienst zurückgegebenen Ergebnisse muss eine Variable erstellt werden, um den zurückgegebenen Wert aufzunehmen, wenn der Vorgang erfolgreich ausgeführt wurde. Öffnen Sie hierzu Workflow1.cs (oder Workflow1.vb, falls Sie eine Visual Basic-Projektmappe erstellt haben), und führen Sie die folgenden Schritte aus:
Erstellen Sie in der
ClientWorkflow-Klassendefinition wie im folgenden Beispiel gezeigt eine öffentliche Eigenschaft mit dem NamenreturnedValue.Public class ClientWorkflow Inherits SequentialWorkflowActivity Public inputValue As Integer = Nothing Public returnedValue As Integer = Nothing ... End Classpublic sealed partial class ClientWorkflow: SequentialWorkflowActivity { public int inputValue = default(int); public int returnedValue = default(int); public ClientWorkflow() { InitializeComponent(); } ... }Öffnen Sie den Workflow-Designer, und binden Sie im Bereich Eigenschaften returnedValue an die (ReturnValue)-Aktivitätseigenschaft. Klicken Sie dazu auf die Schaltfläche mit den Auslassungszeichen, und wählen Sie auf der Registerkarte Binden an einen vorhandenen Member die Option returnedValue aus.
Implementieren Sie einen Ereignishandler für das AfterResponse-Ereignis, um die vom Dienst zurückgesendete Nachricht anzuzeigen.
private void sendActivity2_AfterResponse(object sender, SendActivityEventArgs e) { Console.WriteLine("The value after invoking the Add operation is {0}", returnedValue); }
Binden Sie für jede der anderen mathematischen Operationen inputValue und returnedValue an n1 bzw. (ReturnValue).
Implementieren Sie wie in den Schritten 24c und 25c Ereignishandler für die Ereignisse BeforeSend und AfterResponse in jeder verbleibenden SendActivity-Aktivität, die einer mathematischen Operation zugeordnet ist. Das folgende Beispiel zeigt die Implementierung für alle Ereignishandler, einschließlich des Handlers für die dem
ShutdownService-Vorgang zugeordnete SendActivity-Aktivität.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 Subprivate 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."); }Fügen Sie in Program.cs (oder Module1.vb in Visual Basic) ChannelManagerService zur Liste der Dienste hinzu, die von WorkflowRuntime zum Zwischenspeichern von Kanälen und Kanalfactorys verwendet werden. Die Verwendung von ChannelManagerService ist optional. Verwenden Sie ihn jedoch nicht, werden die Kanäle nicht zwischengespeichert, und von jeder SendActivity-Aktivität in einem Workflow wird eine neue Kanalinstanz zur Kommunikation mit dem Dienst verwendet.
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 Subusing(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(); }Löschen Sie ein Befehlszeilenargument aus den WorkflowServiceTutorial-Projekteigenschaften, um den Client mit der in Übung 1 erstellten WorkflowServiceTutorial-Lösung zu verwenden. Gehen Sie hierzu folgendermaßen vor:
- Klicken Sie mit der rechten Maustaste auf den WorkflowServiceTutorial-Projektknoten, und wählen Sie Eigenschaften aus.
- Wählen Sie die Registerkarte Debuggen aus, und entfernen Sie im Detailbereich unter Start Optionen die Option /client:"WfcTestClient.exe" aus dem Textfeld.
Klicken Sie mit der rechten Maustaste auf den WorkflowServiceTutorial-Lösungsknoten, und wählen Sie Eigenschaften aus.
Wählen Sie im Dialogfeld Eigenschaftenseite die Option Mehrere Startprojekte aus.
Ist WorkflowServiceTutorial nicht als oberstes Element in der Liste aufgeführt, verschieben Sie es mithilfe der Pfeiltasten auf der Seite des Listenfelds an die oberste Position. Dies ist erforderlich, damit die Ausführung des Diensts gestartet wird, bevor von der Clientanwendung versucht wird, Vorgänge auf dem Dienst aufzurufen.
Ändern Sie für jedes Projekt in der Liste die Aktion von Keine in Start.
Klicken Sie auf Übernehmen und anschließend auf OK.
Falls Sie eine Visual Basic-Projektmappe erstellt haben, klicken Sie im Bereich Projektmappen-Explorer mit der rechten Maustaste auf den WorkflowServiceClient-Projektknoten, und wählen Sie Eigenschaften aus.
Wählen Sie die Registerkarte Anwendung aus, und entfernen Sie WorkflowServiceClient aus dem Textfeld Stammnamespace. Andernfalls können Sie keine Verbindung zum Workflowdienst herstellen, weil vom Client auf den falschen Namespace verwiesen wird.
Erstellen Sie die Workflowdienst-Projektmappe, und führen Sie sie aus.
Nachdem der Dienst gestartet wurde, wird die Clientanwendung ausgeführt. Folgendes sollte beim Ausführen der Clientanwendung über die Eingabeaufforderung beachtet werden.
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.
Siehe auch
Weitere Ressourcen
Übung 1: Erstellen eines grundlegenden Workflowdiensts
Copyright © 2007 Microsoft Corporation. Alle Rechte vorbehalten.