Erstellen eines Workflowdiensts mit langer Laufzeit
In diesem Artikel wird beschrieben, wie Sie einen Workflowdienst mit langer Laufzeit erstellen. An einem bestimmten Punkt kann der Workflow in den Leerlauf wechseln und auf weitere Informationen warten. In diesem Fall wird der Workflow in einer SQL-Datenbank beibehalten und aus dem Arbeitsspeicher entfernt. Wenn weitere Informationen für die Workflowinstanz verfügbar sind, wird diese wieder in den Arbeitsspeicher geladen, und die Ausführung wird fortgesetzt.
In diesem Szenario implementieren Sie ein vereinfachtes Bestellsystem. Zunächst wird eine Nachricht vom Client an den Workflow gesendet, um die Bestellung zu beginnen. Die Bestell-ID wird an den Client zurückgegeben. Der Workflowdienst wartet nun auf eine weitere Nachricht vom Client, wechselt in den Leerlauf und wird in der SQL-Datenbank beibehalten. Wenn die nächste Nachricht vom Client mit der Bestellung eines Artikels empfangen wird, wird der Workflowdienst wieder in den Arbeitsspeicher geladen, und die Bestellung wird abschließend bearbeitet.
In dem Codebeispiel wird eine Zeichenfolge zurückgegeben, die angibt, dass der Artikel der Bestellung hinzugefügt wurde. Das Codebeispiel ist nicht als reale Anwendung der Technologie gedacht. Es soll vielmehr auf einfache Weise einen Workflowdienst mit langer Laufzeit veranschaulichen.
Voraussetzungen
Sie müssen folgende Software installiert haben, um diese exemplarische Vorgehensweise verwenden zu können:
- Microsoft SQL Server 2008
- Visual Studio 2012
- Microsoft .NET Framework 4.6.1
Sie müssen auch mit WCF und Visual Studio 2012 vertraut sein und wissen, wie Projekte/Lösungen erstellt werden.
Einrichten der SQL-Datenbank
Damit Workflowdienstinstanzen beibehalten werden können, muss Microsoft SQL Server installiert sein, und Sie müssen eine Datenbank konfiguriert haben, in der die beibehaltenen Workflowinstanzen gespeichert werden können. Um Microsoft SQL Management Studio auszuführen, klicken Sie auf Start, und wählen Sie Alle Programme > Microsoft SQL Server 2008 > Microsoft SQL Management Studio aus.
Klicken Sie auf die Schaltfläche Verbinden, um sich bei der SQL Server-Instanz anzumelden.
Klicken Sie in der Strukturansicht mit der rechten Maustaste auf Datenbanken, und wählen Sie Neue Datenbank aus, um die neue Datenbank
SQLPersistenceStore
zu erstellen.Führen Sie die Skriptdatei SqlWorkflowInstanceStoreSchema.sql unter C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en in der SQLPersistenceStore-Datenbank aus, um die erforderlichen Datenbankschemas einzurichten.
Führen Sie die Skriptdatei SqlWorkflowInstanceStoreLogic.sql unter C:\Windows\Microsoft.NET\Framework\v4.0\SQL\en in der SQLPersistenceStore-Datenbank aus, um die erforderliche Datenbanklogik einzurichten.
Erstellen des im Internet gehosteten Workflowdiensts
Erstellen Sie eine leere Visual Studio 2012-Projektmappe mit dem Namen
OrderProcessing
.Fügen Sie der Projektmappe ein neues Projekt für eine WCF-Workflowdienstanwendung mit dem Namen
OrderService
hinzu.Wählen Sie im Dialogfeld mit den Projekteigenschaften die Registerkarte Web aus.
Wählen Sie unter Startaktion die Aktion Bestimmte Seite aus, und geben Sie
Service1.xamlx
an.Wählen Sie unter Server den Eintrag Lokalen IIS-Webserver verwenden aus.
Warnung
Sie müssen Visual Studio 2012 im Administratormodus ausführen, um diese Einstellung vorzunehmen.
Mit diesen beiden Schritten wird das Workflowdienstprojekt konfiguriert, das von IIS gehostet werden soll.
Öffnen Sie ggf.
Service1.xamlx
, und löschen Sie die vorhandenen Aktivitäten ReceiveRequest und SendResponse.Wählen Sie die Aktivität Sequenzieller Dienst aus, klicken Sie auf den Link Variablen, und fügen Sie die Variablen aus der folgenden Abbildung hinzu. Dadurch werden einige Variablen hinzugefügt, die im weiteren Verlauf in diesem Workflow verwendet werden.
Hinweis
Wenn „CorrelationHandle“ nicht in der Dropdownliste für den Variablentyp enthalten ist, wählen Sie aus der Dropdownliste die Option Nach Typen suchen aus. Geben Sie „CorrelationHandle“ im Feld Typname ein, wählen Sie „CorrelationHandle“ aus dem Listenfeld aus, und klicken Sie auf OK.
Verschieben Sie eine ReceiveAndSendReply-Aktivitätsvorlage per Drag & Drop in die Aktivität Sequenzieller Dienst. Diese Gruppe von Aktivitäten empfängt eine Nachricht von einem Client und sendet eine Antwort.
Wählen Sie die Receive-Aktivität aus, und legen Sie die hervorgehobenen Eigenschaften fest, wie in der folgenden Abbildung veranschaulicht.
Mit der DisplayName-Eigenschaft wird der angezeigte Name für die Receive-Aktivität im Designer festgelegt. Mit der ServiceContractName-Eigenschaft und der OperationName-Eigenschaft wird der Name des Dienstvertrags und des Vorgangs angegeben, die von der Receive-Aktivität implementiert werden. Weitere Informationen zur Verwendung von Verträgen in Workflowdiensten finden Sie unter Verwenden von Verträgen im Workflow.
Klicken Sie in der ReceiveStartOrder-Aktivität auf den Link Definieren, und legen Sie die Eigenschaften fest, wie in der folgenden Abbildung veranschaulicht. Beachten Sie, dass das Optionsfeld Parameter ausgewählt und der Parameter
p_customerName
an die VariablecustomerName
gebunden ist. Dadurch wird die Receive-Aktivität konfiguriert, um einige Daten zu empfangen und an lokale Variablen zu binden.Wählen Sie die SendReplyToReceive-Aktivität aus, und legen Sie die hervorgehobene Eigenschaft fest, wie in der folgenden Abbildung veranschaulicht.
Klicken Sie in der SendReplyToStartOrder-Aktivität auf den Link Definieren, und legen Sie die Eigenschaften fest, wie in der folgenden Abbildung veranschaulicht. Beachten Sie, dass das Optionsfeld Parameter ausgewählt und der Parameter
p_orderId
an die VariableorderId
gebunden ist. Mit dieser Einstellung wird festgelegt, dass von der SendReplyToStartOrder-Aktivität ein Wert vom Typ Zeichenfolge an den Aufrufer zurückgegeben wird.Verschieben Sie eine Assign-Aktivität per Drag & Drop zwischen der Receive- und der SendReply-Aktivität, und legen Sie die Eigenschaften fest, wie in der folgenden Abbildung veranschaulicht:
Dadurch wird eine neue Bestell-ID erstellt, und der Wert wird in der orderId-Variablen platziert.
Wählen Sie die ReplyToStartOrder-Aktivität aus. Klicken Sie im Eigenschaftenfenster auf die Schaltfläche mit den Auslassungspunkten (...) für CorrelationInitializers. Klicken Sie auf den Link Initialisierer hinzufügen, geben Sie im Initialisierertextfeld
orderIdHandle
ein, wählen Sie „Abfragekorrelationsinitialisierer“ für den Korrelationstyp aus, und wählen Sie dann im Dropdownfeld für XPath-Abfragen den Eintrag „p_orderId“ aus. Diese Einstellungen werden in der folgenden Abbildung gezeigt. Klicken Sie auf OK. Dadurch wird eine Korrelation zwischen dem Client und dieser Instanz des Workflowdiensts initialisiert. Wenn eine Nachricht mit dieser Bestell-ID empfangen wird, wird sie an diese Instanz des Workflowdiensts weitergeleitet.
Verschieben Sie eine andere ReceiveAndSendReply-Aktivität per Drag & Drop an das Ende des Workflows (außerhalb der Sequenz mit der ersten Receive- und der ersten SendReply-Aktivität). Dadurch wird die zweite Meldung empfangen, die vom Client gesendet wurde, und beantwortet.
Wählen Sie die Sequenz mit der neu hinzugefügten Receive- und der neu hinzugefügten SendReply-Aktivität aus, und klicken Sie auf die Schaltfläche Variablen. Fügen Sie die in der folgenden Abbildung hervorgehobene Variable hinzu:
Fügen Sie außerdem
orderResult
als Zeichenfolge imSequence
-Bereich hinzu.Wählen Sie die Receive-Aktivität aus, und legen Sie die Eigenschaften fest, wie in der folgenden Abbildung veranschaulicht:
Hinweis
Denken Sie daran, das Feld ServiceContractName in
../IAddItem
zu ändern.Klicken Sie in der ReceiveAddItem-Aktivität auf den Link Definieren, und fügen Sie die Parameter hinzu, wie in der folgenden Abbildung veranschaulicht. Dadurch wird die Receive-Aktivität konfiguriert, um zwei Parameter zu akzeptieren: die Bestell-ID und die ID des bestellten Artikels.
Klicken Sie auf die Auslassungsschaltfläche CorrelateOn, und geben Sie
orderIdHandle
ein. Klicken Sie unter XPath-Abfragen auf den Dropdownpfeil, und wählen Siep_orderId
aus. Dadurch wird die Korrelation für die zweite Receive-Aktivität konfiguriert. Weitere Informationen zu Korrelationen finden Sie unter Korrelation.Verschieben Sie die If-Aktivität per Drag & Drop unmittelbar hinter die ReceiveAddItem-Aktivität. Diese Aktivität verhält sich analog zu einer Anweisung.
Legen Sie die Condition-Eigenschaft auf
itemId=="Zune HD" (itemId="Zune HD" for Visual Basic)
fest.Verschieben Sie eine Assign-Aktivität per Drag & Drop in den Abschnitt Then und eine andere in den Bereich Else, und legen Sie die Eigenschaften der Assign-Aktivitäten fest, wie in der folgenden Abbildung veranschaulicht.
Wenn die Bedingung
true
ist, wird der Abschnitt Then ausgeführt. Wenn die Bedingungfalse
ist, wird der Abschnitt Else ausgeführt.Wählen Sie die SendReplyToReceive-Aktivität aus, und legen Sie die DisplayName-Eigenschaft fest, wie in der folgenden Abbildung veranschaulicht.
Klicken Sie auf den Link Definieren. in der SetReplyToAddItem-Aktivität, und konfigurieren Sie diese, wie in der folgenden Abbildung veranschaulicht. Dadurch wird die SendReplyToAddItem-Aktivität so konfiguriert, dass der Wert in der
orderResult
-Variable zurückgegeben wird.
Öffnen Sie die web.config-Datei, und fügen Sie folgende Elemente im Abschnitt <behavior> hinzu, um die Workflowpersistenz zu aktivieren. (Denken Sie daran, die Verbindungszeichenfolge zu vervollständigen.)
<sqlWorkflowInstanceStore connectionString="...;Asynchronous Processing=True" instanceEncodingOption="None" instanceCompletionAction="DeleteAll" instanceLockedExceptionAction="BasicRetry" hostLockRenewalPeriod="00:00:30" runnableInstancesDetectionPeriod="00:00:02" /> <workflowIdle timeToUnload="0"/>
Erstellen Sie die Projektmappe.
Erstellen einer Clientanwendung zum Aufrufen des Workflowdiensts
Fügen Sie der Projektmappe ein neues Konsolenanwendungsprojekt mit dem Namen
OrderClient
hinzu.Fügen Sie dem
OrderClient
-Projekt Verweise auf die folgenden Assemblys hinzu:System.ServiceModel.dll
System.ServiceModel.Activities.dll
Fügen Sie dem Workflowdienst einen Dienstverweis hinzu, und geben Sie
OrderService
als Namespace an.Fügen Sie der
Main()
-Methode des Clientprojekts den folgenden Code hinzu:static void Main(string[] args) { // Send initial message to start the workflow service Console.WriteLine("Sending start message"); StartOrderClient startProxy = new StartOrderClient(); string orderId = startProxy.StartOrder("Kim Abercrombie"); // The workflow service is now waiting for the second message to be sent Console.WriteLine("Workflow service is idle..."); Console.WriteLine("Press [ENTER] to send an add item message to reactivate the workflow service..."); Console.ReadLine(); // Send the second message Console.WriteLine("Sending add item message"); AddItemClient addProxy = new AddItemClient(); AddItem item = new AddItem(); item.p_itemId = "Zune HD"; item.p_orderId = orderId; string orderResult = addProxy.AddItem(item); Console.WriteLine("Service returned: " + orderResult); }
Erstellen Sie die Projektmappe, und führen Sie die
OrderClient
-Anwendung aus. Der folgende Text wird vom Client angezeigt:Sending start messageWorkflow service is idle...Press [ENTER] to send an add item message to reactivate the workflow service...
Um zu überprüfen, ob der Workflowdienst beibehalten wurde, starten Sie SQL Server Management Studio, indem Sie im Startmenü auf Alle Programme > Microsoft SQL Server 2008 > SQL Server Management Studio klicken.
- Erweitern Sie im linken Bereich Datenbanken > SQLPersistenceStore > Ansichten, klicken Sie mit der rechten Maustaste auf System.Activities.DurableInstancing.Instances, und wählen Sie Erste 1000 Zeilen auswählen aus. Im Bereich Ergebnisse sollte mindestens eine Instanz aufgeführt sein. Es kann sein, dass auch Instanzen früherer Ausführungen aufgelistet sind, wenn Fehler bei der Ausführung aufgetreten sind. Sie können vorhandene Zeilen löschen, indem Sie mit der rechten Maustaste auf System.Activities.DurableInstancing.Instances klicken und Erste 200 Zeilen bearbeiten auswählen. Anschließend klicken Sie auf die Schaltfläche Ausführen, wählen alle Zeilen im Ergebnisbereich aus und klicken auf Löschen. Um zu überprüfen, ob in der Datenbank die Instanz angezeigt wird, die von Ihrer Anwendung erstellt wurde, können Sie überprüfen, ob die Ansicht für Instanzen vor Ausführung des Clients leer ist. Führen Sie die Abfrage (Oberste 1000 Zeilen auswählen) erneut aus, sobald der Client ausgeführt wird, und überprüfen Sie, ob eine neue Instanz hinzugefügt wurde.
Drücken Sie die EINGABETASTE, um die Nachricht zum Hinzufügen des Artikels an den Workflowdienst zu senden. Der folgende Text wird vom Client angezeigt:
Sending add item messageService returned: Item added to orderPress any key to continue . . .