Good evening. Thanks for coming to “Go With the Flow, Understanding Windows
Workflow Foundation.” Tonight I’m going to tell you about one of the most exciting
parts of .NET 3.0, Windows Workflow Foundation. Windows Presentation Foundation
gives you a radically improved graphics toolkit, Communication Foundation is
remoting on steroids. Workflow Foundation is entirely new to the framework, it also
provides tools that haven’t been part of a mainstream toolkit before and certainly not
freely available. It’s quite a radical departure from existing approaches to
My name’s Ben Lamb and I’ve been developing since the days of Visual Basic 2.0.
After that I had brief forays into various 4GLs for web development and Enterprise
Java. A few years ago I started using C# and got hooked on .NET. Nowadays I write
software for investment banks that allows traders to place elaborate bets on the
Throughout this talk when I refer to WF I mean Workflow Foundation.
This talk’s in two parts. In part 1 I’m going to explain what workflows are, then talk
about the features and benefits Windows Workflow Foundation provides. As WF is
closely linked with something called XAML I’m going to briefly explain a minimal
amount of XAML before covering the fundamental concepts behind Windows
Workflow with plenty of demos to break things up.
In part 2 I’m going to look at some of the extra features you get with Workflow
Foundation including Visual Studio integration, the library of ready made activities it
provides, the rules engine and state machines.
When preparing a talk like this I have no idea what you already know about Workflow
Foundation. I’m hoping to give you enough knowledge to make a decision about
whether it’s going to be useful to you. Enough knowledge to start using it and make
sense of the documentation and hopefully whet your appetite with some of the more
I’m not going to cover every last bit of functionality as it’s a huge subject, I’ll list some
of things I didn’t cover at the end.
If there’s something that doesn’t make sense as I’m explaining it please interrupt me
and I’ll try and explain it better. Don’t wait until the end. If you have questions that
aren’t immediately related to what I’m discussing I’ll be happy to take them during
the break or at the end.
Windows Workflow Foundation provides a workflow engine for .NET.
Let’s suppose I’m writing an application for an estate agent to help them manage their selling process. The vendor announces
their intention to sell and the agent advertises the property, on the web, in their shop-window and in local newspapers.
The agent hopefully receives offers on the property and passes them onto the vendor. If the vendor accepts an offer the agent
stops advertising the property. If a certain amount of time elapses the agent might decide that the property isn’t going to sell
and some alternative action needs to be taken.
Once an offer is accepted the process moves onto the exchange of contracts between the vendor and the buyer, the transfer of
money and the exchange of keys.
The workflow I’ve just described, hopefully familiar to most of you, involves a number of activities. Some activities have to occur
in a clearly defined order, others such as the different advertising activities can happen concurrently. There might be looping
involved if parts of the process have to be repeated.
The exchange of money and the keys is a transaction. If the keys aren’t handed over the money needs to be returned.
Obviously the estate agent will have multiple properties on their books at any one time so there will multiple instances of the
workflow. As anyone who’s ever sold a property knows the process can take several months to complete. There are also flurries
of activity, nothing happens for ages then there is lots of activity.
Let’s think about how we might code this application using what’s available in .NET 2.0. Obviously we don’t want to keep the
data in memory as we can’t trust the reliability of the machine over several months, the power might get turned off, so we need
a persistent store. If this application was servicing a national chain of estate agents there might be thousands of properties and
we’d like the application to scale without consuming tons of resources.
So at this point I’m thinking of a database table with a row to record each sale and the state in the process that has been
reached. We could imagine the application having a number of methods that would receive external events, do some
processing and then update the state field to reflect the next stage of the workflow. This would mean that each method would
have to have knowledge of the workflow and know what the next stage was.
The state itself might be considerably more complicated than just the name of stage that had been reached. We could get
round this by giving each method a separate database table to store state in, or having a dictionary that could be shared by all
the methods and serialising it to the database.
Concurrent activities and transactions would require more logic to support. Ideally we’d separate the workflow logic from the
code that did the processing and move it into a configuration file so we could update it more easily. It might be very difficult to
show this configuration to the customer and ask them to check it matched their business process.
Finally, the estate agent has different processes for residential and commercial properties, whether the property is being sold or
rented and so forth. When these change the changes affect properties sold after that date, not properties already in the system.
By thinking about the design of an application like this in detail you can appreciate the types of problem Workflow Foundation
is designed to help with. As you can see a relatively straightforward business application, dealing with sales enquiries for an
estate agent, has quite an involved process behind it which would require a lot of coding to make the application robust,
reliable and scalable.
Workflow Foundation supports long running business processes, particularly those
with flurries of activity aka episodic execution. It provides persistence, graphical
modelling of workflows, transactions, tracking and much more besides.
It consists of an engine for running workflows, various services that provide
additional functionality, a GUI for creating workflows, a rules engine and a set of
workflow activities that perform common tasks. These pieces are libraries that are
included with .NET 3.0. You also need to download an add-in for Visual Studio 2005
that gives you a graphical designer and debugger for Visual Studio that we’ll look at
later. This is not necessary, you can code everything using a traditional text editor if
Many of the features are provided as bolt-on services that connect to the core
engine. This means you can pick and choose which bits you require and write your
own implementations of services if necessary. For example, if you want to store a
workflow in a custom file format you write your own loader service.
Even though the core engine is quite small there is still work involved in writing
applications that take advantage of the workflow engine so if you don’t need any of
the features it provides it might be overkill to use it. Hopefully this talk will help you
decide whether it could be of benefit to your project.
Let’s take a break from workflows for a moment and talk about XAML. XAML is a way
of declaring objects in XML, i.e. create me an instance of one-of-those, one-of-those
and one-of-those. Because it’s XML based it’s very suitable for creating trees of
objects. People associate it with WPF but you can use it for any objects.
Central to WF are classes that inherit from a class called Activity. This provides an
Execute method where the activity does it’s work. Composite activities contain one
or more child activities. For example, there is a composite activity called Sequence
which executes each of its child activities in order.
A workflow is simply a tree of activity objects. You can construct this tree
programmatically or write some XAML which the workflow runtime will process and
instantiate all the activity objects listed in it. Workflows have one root activity which
maps very nicely to the single root node you’re allowed in an XML document.
Workflows don’t have to be stored as XAML. The workflow engine uses a loader
service to load a workflow. The default implementation provided by Microsoft loads
workflows from XAML but you could write your own to use any format. You could
also instantiate the objects in C# or VB.Net but it would be rather time consuming
and you’d loose the benefit of separating your business logic from code.
To use the workflow engine you create an instance of WorkflowRuntime. You then
use a loader service to pass in a tree of instantiated objects that represent your
The simplest workflow you can create will consist of one activity. In time honoured
tradition let’s write a “HelloWorld Activity”.
Demo One – My First Workflow
Introduce XAML for workflows
Associating namespaces with classes
Code for HelloWorld activity
Execute method, returns ActivityStatus.Closed
Show code for instantiating and loading WF runtime
Hello World Activity not very generic – replace with PrintSomething Activity
PrintSomething activity, parameters in XAML
Sequence activity – example of composite activity
Data binding using Activity binding
In that demo we covered quite a lot:
How to associate XML namespaces with classes in XAML.
Simple activities and composite activities
Passing data between activities using data binding
All the activities I’ve demonstrated so far have been trivial. They’ve done all the work in the
Execute method and returned a status of ActivityExecutionStatus.Closed back to the
workflow engine. Sometimes an activity might need to wait for an event before it can
complete. In the meantime it must return control to the workflow engine so it should arrange
a callback in its Execute method and return a status of ActivityExecutionStatus.Executing.
That instance of the workflow will remain paused at that activity until that activity completed
but any parallel activities and other workflow instances will be able to continue execution. I’ll
talk more about the scheduling of activities later.
How do we get any activity to respond to an external event and continue execution when the
event is received?
Workflow queues are used to provide asynchronous communication between activities and
the outside world. The queuing service provides a means of using queues. One of the
parameters to the Execute method is an ActivityExecutionContext, this provides a GetService
method that returns any required service. For example:
WorkflowQueuingService queuingService = context.GetService<WorkflowQueuingService>();
We can then create a queue:
Workflow queue = queuingService.CreateWorkflowQueue(this.Name, true);
The first parameter is the queue name, the second parameter indicates whether the queue is
Queues have a QueueItemAvailable event that we can use to call the callback method.
queue.QueueItemAvailable += this.GetOnWithTheWork;
void GetOnWithTheWork(object sender, QueueEventArgs e)
The sender will actually be the ActivityExecutionContext which we can use to get to the
queuing service and from that dequeue the item. Finally as the callback method returns void
we call context.CloseActivity() to indicate that the activity has completed processing.
One problem with the last example is that the queue only gets created when the
activity is first executed. This means that if events arrive before that happens they
won’t be able to add items to the queue as it won’t exist.
The lifecycle of a workflow activity is slightly different to a normal CLR object. At
various points the workflow engine might decide to passivate instances of workflows
to disk which means all the activity objects belonging to that instance will be
disposed of. This means that an activity’s constructor is potentially called more than
once when the engine recreates the instance.
This isn’t necessarily a problem; you could still use the activity’s constructor to create
the queue but would have to check to see whether it had already been created.
The preferred approach is to use the activity’s Initialise() and Uninitialise() methods.
Initialise() is called on all activities when the workflow instance is created. If an
exception is thrown creation of the workflow will fail. Uninitialise should clean up any
resources used by the activity, e.g. delete queues, when the activity has completed.
With long running processes you don’t want to keep everything in memory just in
case the computer fails. Also, if you’ve got 10,000 instances of a workflow the
memory requirements could get horrendous.
WF provides a PersistenceService which saves workflow instances to a database. The
service only supports Microsoft SQL Server so if you want to save state to anywhere
else you’ll have to write your own implementation of persistence service. Also
supplied are two stored procedures which create the required schema in your
Using the PersistenceService is quite easy, you instantiate the persistence service,
giving it a connection string and then add the service to the workflow runtime. By
default any idle workflow is persisted. An idle workflow is one stuck on an activity
that is waiting for a callback.
There is a PersistOnIdle property that, if set to true, will persist idle workflows to the
database. An “idle” workflow is one with no items in the scheduled work queue.
Workflows are single threaded. You are well advised not to try creating threads inside your
activities. The workflow runtime relies on activities returning control asap. If they have to
wait for something they should return control to the runtime and use a queue to receive the
event as described earlier.
In this way the runtime can provide the illusion of parallel activities and also run thousands of
workflow instances simultaneously. If you do have 10,000 workflows you do not want them
all running on an individual thread. However, if you have a multi-core or multi-processor
machine it makes sense to use several threads to take advantage of your hardware. WF does
this but different workflow instances will be run on different threads. The scheduler service is
responsible for creating threads and deciding what gets run where.
This means your activities don’t have to worry about locking or being interrupted midway
through execution. There are some higher level synchronisation primitives that allow you do
locking to ensure that an activity doesn’t start whilst another, specified, activity is in progress.
The scheduler maintains a scheduler work queue, which your program has no direct control
over, that is a list of items to execute. Any transition of activity state, or arrival of a queue
item will put an entry on the scheduler’s work queue.
The default scheduler will create a new thread for every workflow instance, up to a certain
limit dependent on the number of processors available. An alternative implementation is
provided that uses the current thread to execute the workflow instance. This would be
problematic under normal circumstances as you’d only be able to execute one instance at a
time. However, it’s designed for scenarios such as running workflows in response to web
request where the web service, e.g. IIS, had already created a thread to serve the request.
Sometimes it might be necessary to cancel an activity. For example, if you run two
activities in parallel you might want to proceed as soon as one of them completes
and not care about the result of the others. For example, the estate agent will
advertise houses in several places and as soon as enquiry comes in proceed to the
next step. They don’t want to wait for enquiries from the newspaper ad, the shop
window ad and the website before proceeding.
In this case you’ll want to cancel the other activities. When this happens the activity
moves into a Cancelling state and a Cancel method is called. By default this returns
ActivityExecutionStatus.Closed and the object moves into a Closed state. A property
on the activity called ExecutionResult is set to Cancelled by the runtime.
The Cancel method can perform any cleanup operations required. It’s important to
note that Cancel might be called without Execute ever being called.
As activities are normal .NET code when something goes wrong an exception is
thrown. In WF exceptions are known as faults as the fault handling process is slightly
different to the way exceptions are usually handed in .NET.
If an exception is thrown the activity moved into Faulting state and the HandleFault
method is scheduled by the runtime. Unlike normal .NET code where the exception
handling code is executed immediately it could be some time before the HandleFault
method is called.
The activity should perform any cleanup in HandleFault and then return a status of
Closed to indicate that the activity has finished processing. N.B. The activity does not
get another chance to execute. If you want to recover from exceptions you should
include exception handling code in your Execute method.
If the activity’s clean up tasks are going to take a long time, e.g. it has to wait for a
response from an external service, it can return a status of Faulting and setup the
appropriate callbacks. Eventually it must transition to the Closed state.
Activities have a property called ExecutionResult, this will be set to Faulted by the
runtime. Once the activity is completed the runtime will propagate the exception to
the parent activity unless the HandleFault method tells it not to. The default
implementation of HandleFault simply returns ActivitiyExecutionStatus.Closed.
When a composite activity receives a fault it will cancel the other activities e.g. in a
sequence of three activities if the third activity faults then the other two activities
that have already executed will be cancelled.
If an exception is thrown by an activity’s Initialise method the exception is propagated
to the CreateWorkflow method which calls Initialise which turn throws an exception
indicating the workflow instance cannot be created.
Our state transition diagram for an activity now looks like this. An activity starts in
Initialising, moves to Executing and ends up in the Closed state. If it gets cancelled
before it has completed it will transition to the Cancelling state. If an error occurs
whilst it is in the Executing or Cancelling states it will transition into the Faulting state.
If that wasn’t complicated enough there is another state, Compensation.
The idea of compensation is to reverse the effects of an activity. If you have a
TurnLightOn activity the compensation code can turn the light off again. In this case
the compensation action is simply to do the opposite of the activity’s normal action.
If you have an EatCake action the compensation code will have to be slightly different
as it is not possible to directly reverse the action.
Sure enough when the activity transitions to the Compensating state a method called
Compensate is called. Note, the activity must implement ICompensatableActivity in
order to support compensation.
That’s been a whistle-stop tour of the basic concepts behind Windows Workflow.
We’ve looked at the types of problems WF aims to help with. Seen how workflows
consist of activity trees that are executed by the workflow runtime. Covered basic
XAML. Looked at the lifecycle of an activity, how it is initialised and what happens
when it is passivated by the runtime. I’ve explained how runtime’s scheduling service
works and how the model for handling exceptions, known as fault handling differs
from normal exception handling. The activity is moved to a faulting state and its
HandleFault method is scheduled.
It’s a huge amount of stuff. I’ve tried not to go into every last detail but still cover the
In part 2 we’re going to look at the ready-made activities that come with Workflow
Foundation. Then see how you can design workflows graphically in Visual Studio
rather than writing the XAML yourself.
Workflow foundation includes a rules engine and also supports a slightly different
type of workflow known as a state machine.
Finally, I’m going to run through a list of other things that workflow foundation does
but I haven’t covered in this talk.
Workflow Foundation comes with a set of activities covering things such as: flow
control, calling code and error handling.
Rather than writing workflows in XAML you can download an extension that lets you
design them graphically in Visual Studio and it generates the XAML behind the scenes
in very similar manner to the way the Windows Forms designer automatically
Most business processes incorporate decisions. “Is customer under 18? then deny alcohol purchase?”, “If order total greater
than £10 and it’s the customer’s first order then apply discount.” Often the rules will change from time to time so it makes sense
to include them as part of the workflow rather than hard-coding them into the activities. A condition is an expression that
returns a boolean result. WF provides activities as part of the base activity library that use conditions such as IfElse and While.
These activities have a Condition property that takes an ActivityCondition object which has a method called Evaluate which
returns a boolean. There is an object called CodeCondition that simplifies the process of writing a condition in code. Rather than
write a new class that inherits from ActivityCondition you implement a delegate called Condition that sets a property, Result.
This means you can write a single method rather than an entire class. In the Visual Designer this is nicely wrapped up so that
you simply enter a name of the delegate and it creates the appropriate method in the code behind file.
It is even possible to put code into XAML using a CDATA section but this is not recommended.
The alternative to writing conditions in code is to use declarative conditions. These are expressions that can be evaluated
Conditions are useful whether the result is a Boolean. Most businesses have more complicated policies to calculate shipping
rates, customer discounts and reorder quantities. The workflow foundation includes a rules engine. A rule consists of a
condition, some “then” actions that are executed if the condition is met and some “else” actions that are executed if the
condition is not met. An action in this context means setting a variable.
A rule set is a collection of rules. Each rule has a name, priority, can be enabled or disabled, and a re-evaluation property.
The base activity library includes a Policy activity which will evaluate a ruleset. Rulesets are stored as XML. Workflow
Foundation includes a graphical rules editor that you can use from Visual Studio or in your own application. Using the graphical
editor is preferable as the XML is very verbose.
The idea is you can execute a ruleset using the Policy activity and use it to set various properties for use by the rest of the
workflow, for example, level of customer discount.
Rules within a ruleset may have dependencies on each other. For example: You might have several criteria for giving a customer
a discount. They might get 5% off if it’s their first order. 5% for paying by cash. 5% for collecting the order themselves. You might
want to cap the discount at 10% so you can order the rules within the ruleset and have a final rule that sets the discount to 10%
if it is greater than 10%.
This is where the rule priorities come in.
Sometimes the relationship between rules is more complicated where the output of one rule is used as the input to another. For
example a rule calculating the customer’s credit score might affect the discount applied. The WF rules engine supports
something called rule changing. This has three values, sequential, explicit or full chaining. Sequential is like the situation just
described where the rules are evaluated in priority order once only.
Explicit means that rules can be re-evaluated if another rule explicitly requests it. Full chaining means that rules engine will work
out whether a rule needs to be re-evaluated. Full chaining needs to be used with caution as it could lead to an infinite loop.
The reevaluation property on each rule can be used to ensure that a rule only executes once.
The type of workflows I’ve demonstrated so-far are known as sequential workflows.
The activities are executed in a pre-defined sequence once only. The activity decides
when it has completed and the runtime then schedules the next step.
An alternative type of workflow is known as a state machine workflow. In this
situation some external process tells the runtime engine when to move between
While sequential workflows are very suited to long-running business processes. I can
see state machines being used for quite short-lived operations. Being able to
graphically model a complex state diagram and having transitions between states
enforced so that any attempt to make an invalid transition throws an exception has
got to be better than trying to code one with if statements.
A big part of Workflow Foundation is the visual design tools as you can incorporate
them into your application as well as using them from Visual Studio. This provides the
possibility of modifying the behaviour of an application once it’s shipped using a
graphical tool without having to recompile anything. This will either excite you or fill
you with horror depending on which industry you work in.
It’s just possible you might be able to create something that’s easy enough for a non-
developer to use, e.g. a business analyst. They could go in a create new workflows for
new business processes based around custom activities written by you. The activities
would draw themselves nicely in the designer using custom designers and have
extensive validation associated with them.
The rules engine is also very powerful and potentially gives you a lot of rope to hang
There are a whole load of events, properties and methods provided by the workflow
runtime and activities. These are fairly easy to understand by reading the docs.
We’ve looked at a number of services you can use with Windows Workflow including
the persistence service, the loader service, the queuing service. We’ve been using the
supplied implementations but you can write your own or use other people’s. For
example: there are queuing services that work with WCF, Amazon Queuing Service
and the Amazon Mechanical Turk. You could write a loader to create a workflow from
a custom file format rather than XAML. I’d like to see but can’t find persistence
services for other databases apart from SQL Server. There is an example in the docs
that shows how to persist to text files.
The runtime engine can load service implementations based on a configuration file.
WF includes a tracking service that reports on the status of all workflows and their
activities. It is highly configurable but I don’t have time to go into the details.
There is quite a lot of detail around fault, cancellation and compensation that I
haven’t covered. For example, it is possible to attach special handlers that to
composite activities that get called if activities go into any of these states. You can
think of a FaultHandler as a try/catch block and it can be programmed to handle
It is possible to modify a running workflow instance.
The graphical designer and all the other workflow bits you saw me demonstrate in
Visual Studio can be used in your own applications. It is possible to write custom
designers and validators for your activities so they integrate with the designer. The
designer even supports themes so you can control the fonts, colours and various
other options used to render activities on-screen.
As you can see there is tons of stuff in Workflow Foundation.
Books on .NET 3.0 are only just hitting the shelves. Make sure you avoid anything that
hasn’t been published in the last two months as it probably refers to one of the beta
versions and much has changed.
I found “Essential Windows Workflow Foundation” by Dharma Shukla and Bob
Schmidt very helpful, both members of the development team at Microsoft. It covers
the fundamentals and provides a good insight into the way Workflow Foundation was
designed. It says nothing about the base activity library or state machine workflows.
It also doesn’t really give any examples of how you would practically use the
technology. Several of the reviews on Amazon criticise it for this.
There are a number of good blogs and useful articles on the web. The documentation
supplied with .NET 3.0 isn’t very helpful unless you’re already familiar with the
concepts involved. Hopefully as a result of this talk it will be more useful to you.
Better are the Hands-on Labs for Workflow Foundation, and other .NET 3.0
technologies, that you can download from MSDN. They don’t seem to have been
updated for the RTM version of WF.
Windows Workflow Foundation Hands-on Labs