Windows Workflow Foundation (WF) and ASP.NET

Windows Workflow Foundation (WF) is an exciting addition to .NET development framework, which makes developing enterprise Workflow application easier -- You need not worry about maintaining states for each activity inside WF. As most of the enterprise applications are web-based, I am more curious how WF can integrate with ASP.NET framework.

Let's take a brief look at how WF and ASP.NET work separately.

WF: WF runtime creates a WF instance that is defined by developer using workflow designer or XOML (a XAML configuration file). Then the instance is started to process passed-in parameters (for sequential workflow) or wait for an event to trigger a series of activities (for state machine workflow). To avoid blocking front-end application, by default the WF instance runs asynchronously using another thread. When WF instance is idle (e.g. while waiting for human intervention), the instance is serialized and saved in database. Later, when certain event happens, the instance will be deserialized and continue to process from former state. A sample of WF code is like below:

// Get a reference to the Workflow runtime
WorkflowRuntime wr = WorkflowWebRequestContext.Current.WorkflowRuntime;

// Attach to the WorkflowCompleted event
wr.WorkflowCompleted += new EventHandler<workflowcompletedeventargs>(CallbackMethodWhenCompleted);

// Create workflow instance
WorkflowInstance workflowInstance = wr.CreateWorkflow(typeof(Samples.HelloWorkflow), parameters);

// Start the workflow instance

ASP.NET: ASP.NET runs synchronously for each request. There is no relationship between each request. After the request is processed, a response will be returned.

1) The synchronous ASP.NET and asynchronous WF makes integration a little bit complex. If ASP.NET code call WF runtime to create an instance to run without special configuration, ASP.NET code will return directly without waiting for the WF instance to finish -- This is not what we want.

2) When a new request comes, ASP.NET cannot create a new WF runtime. Because WF runtime cannot be loaded more than once in the same AppDomain.

To solve the first problem, uses the <workflowruntime> configuration section in the configuration file to store information to include WorkFlowPersistenceService and WorkFlowSchedulerService. The former service automatically persists the workflow instance to the specified database as soon as the workflow becomes idle. The second service ensure that the ASP.NET thread in charge of executing the current request waits until the workflow is completed, in another word, the service guarantees that the execution of the workflow is synchronous and that the Start() method returns only when the workflow has ended or is idle.

For example, the configuration part can be like below:

<WorkflowRuntime Name="WorkflowServiceContainer">
<add type=
System.Workflow.Runtime, ..." />
<add type=
System.Workflow.Runtime, ..." />

To solve the second problem, WF provides WorkflowWebRequestContext to provide unique runtime instance in an AppDomain (see above code example).