First step is setting up the new persistence databases. Go to “C:\Windows\Microsoft.NET\Framework\v4.0.30319\SQL\en” and there you will find two files:
In SQL Server (Express or above), create a database with a convenient name (my database is called “SqlWorkflowInstanceStore”) and run the above scripts to create the required objects.
The persistence model in WF 4 is different than that of WF 3.5. the new model is now called InstanceStore instead of PersistenceProvider. For WF 3.5, the PersistenceProvider databases are still available in the same location:
In WF 3.5 there was service for managing WFs such as waking up workflow instances… the SQL files for this service is also still available in the same location:
For tracking in 4.0 there is no tracking participant that writes to a SQL. The Tracking_Schema.sql applies to 3.5 WFs. Out of the box with WF 4.0 there is a tracking participant that writes to ETW (Event Tracing for Windows). Again, those files for WF 3.5 are:
The Receive and SendReplyToReceive shape receives an empty request and returns the workflow instance id to the caller. The CodeAcitivty1 is a custom activity that retrieves the workflow instance id. Below is the code for this activity:
The important catch is to set the property PersistBeforeSend on the SendReplyToReceive shape. This will cause the WF to persist just before sending the response to the caller. This means that now the WF will have a point to go back to in case the WF is suspended or unloaded…more on that later.
The Delay activity is used to delay the WF for 1 minute…we will see why is that required after moments.
Now go to the Program.cs file and let’s write the code required to host the WF and set up persistence.
Use the following code and then I will explain it:
By default, the WorkflowInvoker is used to invoke the WF. I changed this into the WorkflowServiceHost, the reason is that the WorkflowInvoker cannot be configured with Persistence. WorkflowServiceHost is used to host WF Services. The other method of calling (hosting) workflows is the WorkflowApplication which – like WorkflowServiceHost – can be used to host long running asynch workflows with extensions (Persistence, Tracking) however only for workflows that are non services.
After creating my WCF endpoint and adding it to the host, I use the SqlWorkflowInstaceStore class to configure my persistence store, which is the same store I prepared when I first started.
Creating the Client
Run the WF so that the host is running and the WCF endpoint is listening for requests on “http://localhost:8089/TestWF”
Now create a client (console) application and add a service reference to the above URL. Write the following code to invoke the service operation:
Run the client and observe the scenario: once the operation is invoked (and the workflow instance id is returned), open the table “InstancesTable” and you will see a record for a persisted WF. Why is that? Recall that we set a property on the SendReply shape to persist just before sending the reply. For this the WF has persisted state in the database but is still running as we did not suspend or unload the WF. See images below:
For how much time will this record appear in the database? For 1 minute because we have a delay shape in the WF to delay completion for 1 minute after which the WF execution will complete and the record will disappear from the database.
In part 2 I will add support (behavior) to persist and unload the WF as well as add control endpoint to execute remote operations on the WF.