Understanding the Workflow Runtime Engine
A single .NET assembly can define multiple workflow instances. Furthermore, you can easily build workflow *.dlls that enable you to reuse workflows across multiple projects or .NET languages. You must inform the WF runtime engine which workflow instance to execute and when.
From a high level, a WF-enabled application consists of the following:
- A workflow instance and the activities that represent it.
- An instance of the workflow runtime engine, which will execute the workflow instance.
- An application domain to host the runtime (only one runtime object per AppDomain).
The WF API has been designed to be as modular as possible. If required, your WF-enabled application could bundle the workflow instance, runtime, and hosting logic within a single .NET executable. On the other hand, each aspect of a WF-enabled application could be placed in reusable .NET assemblies. In any case, the high- level composition of a WF application looks like this:
The WorkflowRuntime class represents the WF engine itself. This type is within the System.Workflow. Runtime namespace of the System.Workflow.Runtime.dll assembly.
The WorkflowRuntime type provides only one property of any real interest. The IsStarted property allows you to determine if a WorkflowRuntime has started to execute.
The WorkflowRuntime type defines a number of events that allow you to intercept various states of runtime execution. Here are some key events of WorkflowRuntime, many of which you will see during your lab time.
|Started||Occurs when the workflow runtime engine is started.|
|Stopped||Occurs when the workflow runtime engine is stopped.|
|WorkflowAborted||Occurs when a workflow instance is aborted.|
|WorkflowCompleted||Occurs when a workflow instance has completed.|
|WorkflowCreated||Occurs when a workflow instance has been created.|
|WorkflowIdled||Occurs when a workflow instance enters the idle state.|
|WorkflowLoaded||Occurs when the workflow instance is loaded into memory.|
|WorkflowPersisted||Occurs when the state of a workflow instance is persisted.|
|WorkflowResumed||Occurs when execution of a workflow instance is resumed following a suspension.|
|WorkflowStarted||Occurs when a workflow instance has been started.|
|WorkflowSuspended||Occurs when a workflow instance is suspended.|
|WorkflowTerminated||Occurs when a workflow instance is terminated.|
|WorkflowUnloaded||Occurs when the workflow instance is unloaded from memory.|
In addition, WorkflowRuntime defines a set of interesting methods. You will see some of these members at work throughout this class. Note that some of these members allow you to add or remove any of the WF services examined earlier in this chapter (persistence, tracking, transactions, and so on). Others allow you to enumerate / locate workflow instances hosted by the current runtime.
|AddService()||Adds the specified service to the workflow runtime engine.|
|CreateWorkflow()||Creates a workflow instance by using the specified parameters.|
|GetAllServices()||Retrieves all the services that have been added to the workflow runtime engine that implement or derive from a specified type.|
|GetLoadedWorkflows()||Gets a collection that contains all the workflow instances currently loaded in memory.|
|GetService()||Retrieves a service from the workflow runtime engine by using a specified type.|
|GetWorkflow()||Retrieves the workflow instance that has the specified Guide.|
|RemoveService()||Removes the specified service from the workflow runtime engine.|
|StartRuntime()||Starts the workflow runtime engine and the workflow runtime engine services.|
|StopRuntime()||Stops the workflow runtime engine and the runtime services.|
Hosting the WF Runtime within a Console Application
When you create a console-based WF app, the Main() method contains the necessary logic used to host the initial workflow instance. The WorkflowInstance class represents the workflow instance to execute within the engine.
In C#, the initial code looks like the following. The use of the AutoResetEvent logic simply ensures that the console remains open until the WF has completed. Also notice that the boilerplate code has hooked into two WF engine events by using C# anonymous method syntax.
static void Main(string args)
// Create the WF runtime.
using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
// Hook into WorkflowCompleted / WorkflowTerminated events.
AutoResetEvent waitHandle = new AutoResetEvent(false);
+= delegate(object sender, WorkflowCompletedEventArgs e)
+= delegate(object sender, WorkflowTerminatedEventArgs e)
// Create an instance of the WF to execute and call Start().
WorkflowInstance instance =
In VB, the WorkflowComplete / WorkflowTerminated events are handled via AddHandler statements. This code would be located within the project’s Module1.vb file.
Shared WaitHandle As New AutoResetEvent(False)
Shared Sub Main()
Using workflowRuntime As New WorkflowRuntime()
Dim workflowInstance As WorkflowInstance
' Targets for events.
Shared Sub OnWorkflowCompleted(ByVal sender As Object, _
ByVal e As WorkflowCompletedEventArgs)
Shared Sub OnWorkflowTerminated(ByVal sender As Object, _
ByVal e As WorkflowTerminatedEventArgs)
When you want to host the workflow runtime within other applications, such as a Windows Forms or WPF application, you will author similar code manually. To maximize reuse, you may wish to build a custom class type that encapsulates the details of the runtime plumbing and place it in a dedicated .NET code library. You will examine various ways to do so after your first lab.
Copyright (c) 2008-2013. Intertech, Inc. All Rights Reserved. This information is to be used exclusively as an online learning aid. Any attempts to copy, reproduce, or use for training is strictly prohibited.