How to: Create and Run a Long Running Workflow
This topic applies to Windows Workflow Foundation 4 (WF4).
One of the central features of Windows Workflow Foundation (WF) is the runtime’s ability to persist and unload idle workflows to a database. This topic demonstrates how to create the local database for workflow persistence and how to enable persistence in a workflow application.
Note
Each topic in the Getting Started tutorial depends on the previous topics. To complete this topic, you must first complete How to: Create an Activity, How to: Create a Workflow, and How to: Run a Workflow.
To create the persistence database
Open SQL Server Management Studio and connect to the local server. Right-click the Databases node on the local server, and select New Database. Name the new database Persistence, accept all other values, and select OK.
Note
Ensure that you have Create Database permission on the local server before you try to create a new database.
Right-click the new Persistence database and select New Query. Open the following folder: C:\Windows\Microsoft.NET\Framework\<current version>\sql\en. Drag the following files into the query window and execute them in the following order:
SqlWorkflowInstanceStoreSchema.sql
SqlWorkflowInstanceStoreLogic.sql
To enable persistence in a workflow application
Right-click WorkflowConsoleApplication1 in Solution Explorer and select Add Reference.
Select System.Activities.DurableInstancing and System.Runtime.DurableInstancing from the .NET tab and click OK.
Open Program.cs (Module1.vb for Visual Basic) in the WorkflowConsoleApplication1 project. In the
Program
class (Module1
for Visual Basic), declare a string constant that defines a connection string to the persistence database you created in the first procedure.Const connectionString As String = "Server=.\\SQLEXPRESS;Initial Catalog=Persistence;Integrated Security=SSPI"
const string connectionString = "Server=.\\SQLEXPRESS;Initial Catalog=Persistence;Integrated Security=SSPI";
Note
Depending on your edition of SQL Server, the connection string server name may be different.
Next, add a using or Imports statement for
System.Activities.DurableInstancing
in the Program.cs or Module1.vb file.Imports System.Activities.DurableInstancing
using System.Activities.DurableInstancing;
In the
Main
method following the code that creates the WorkflowApplication, create a SqlWorkflowInstanceStore and assign it to the InstanceStore of the WorkflowApplication.Note
Please replace
Workflow1
in these examples withFlowchartNumberGuessWorkflow
,SequentialNumberGuessWorkflow
, orStateMachineNumberGuessWorkflow
, depending on which workflow you completed in the previous How to: Create a Workflow step.Dim inputs As New Dictionary(Of String, Object) inputs.Add("MaxNumber", 100) Dim wfApp As New WorkflowApplication(New Workflow1(), inputs) Dim store As New SqlWorkflowInstanceStore(connectionString) wfApp.InstanceStore = store
WorkflowApplication wfApp = new WorkflowApplication(new Workflow1(), inputs); SqlWorkflowInstanceStore store = new SqlWorkflowInstanceStore(connectionString); wfApp.InstanceStore = store;
Next, tell the workflow to persist when it goes idle. To do this, replace the delegate for the
Idle
event that was added in the previous topic and replace it with the following code that handles PersistableIdle.' Replace the Idle handler with a PersistableIdle handler. 'wfApp.Idle = _ ' Sub(e As WorkflowApplicationIdleEventArgs) ' idleEvent.Set() ' End Sub wfApp.PersistableIdle = _ Function(e As WorkflowApplicationIdleEventArgs) idleEvent.Set() Return PersistableIdleAction.Persist End Function
// Replace the Idle handler with a PersistableIdle handler. //wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e) //{ // idleEvent.Set(); //}; wfApp.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e) { idleEvent.Set(); return PersistableIdleAction.Persist; };
Note
The PersistableIdleAction enumeration has three values: None, Persist, and Unload. Persist causes the workflow to be persisted but it does not cause the workflow to be unloaded. Unload causes the workflow to persist and be unloaded. After the instance is unloaded, the WorkflowApplication is disposed, and a new WorkflowApplication object is required for the next interaction with the unloaded workflow. In this topic,
Persist
is used so the workflow remains in memory and the WorkflowApplication is not disposed. For an example of using a WorkflowApplication with the Unload enumeration value, see the Persisting a Workflow Application sample.At the end of the
Main
method, add the following lines of code. WorkflowApplication automatically unloads the workflow instance from memory after the game is complete and removes the persistence record from the database.Console.WriteLine("Press any key to continue . . .") Console.ReadKey()
Console.WriteLine("Press any key to continue . . ."); Console.ReadKey();
Note
When the workflow completes, the persistence record for the workflow is removed. In this example, without the Console.ReadKey, the host application would exit immediately when the workflow completed. Because the persistence clean-up occurs on a background thread, it would not get a chance to complete its work if the host terminated before the clean-up was finished. Another way to prevent the host from exiting before the persistence operation completes is for the host to block until the Unloaded event occurs after the workflow completes. After a workflow completes, it is not unloaded until background work such as removing the completed workflow from persistence is complete.
To test persistence, press F5 to start the application and switch back to SQL Server Management Studio. Expand the Persistence database node (or the Master database node if you created the persistence tables in the Master database), and the Tables node within the Persistence database. Right-click the InstancesTable table, and select Select Top 1000 rows. One row should be displayed, with the workflow ID of the persisted workflow.
Next, play through the game to complete the workflow. After the game has exited, go back to SQL Server Management Studio, and execute the query again. Note that no persistence record is returned.
You have completed the Getting Started tutorial.