This is in follow up to a mail I got the other day on a similar theme.
Most Workflows are likely to have state and StateMachine Workflows are no exception.
Workflow Foundation has the idea of a persistence service that can store the state of a particular Workflow Instance in order that the Workflow can be "re-hydrated" at a later point from the persistence store and set running again.
This pretty much happens by magic :-) and as long as the state that you've got in the Workflow definition is Serializable then (as far as I know) you'll be ok.
Workflows aren't going to want to be serialized when they're in the middle of something so typically they're going to be persisted when they're waiting for something to happen (I wrote a little about this from an Activity writer's perspective here). For example - if the Workflow is in a delay or perhaps it's waiting for an external event to occur.
Now, usually, if you've got a Workflow that's waiting for an external event to occur then one way or another what will have happened will have been;
- Workflow instance waits for external activity to occur.
- Source of the external event has been passed the instance id of the instance that's waiting or some other piece of data that can correlate back to the instance id.
- External event occurs (e.g. email received, web service call received, etc)
- Event is fired "into" the Workflow Instance that's waiting for it.
At step (4) above if the instance in question happens to have been persisted then it'll be loaded through the persistence service at this point.
You can imagine hosting Workflow Foundation in a client application where a number of instances are instantiated by a user and when the user starts/stops the application you need to remind the user of the instances that are still kicking around. That is, the user is the source of the external event in step (3) above and if the user forgets that they have Workflow Instances already running on their behalf then step (3) may never happen.
This is different from the situation where instances are waiting for timers because (ultimately) the timers will go off and cause the instances to get re-loaded and then resumed.
If we've got a bunch of persisted Workflow Instances stored in the persistence DB, how do we find out about them when the user starts/stops the application?
At application start-up, a call can be made the SqlWorkflowPersistenceService which has a method on it called GetAllWorkflows which will return back a list of SqlPersistenceWorkflowInstanceDescription. From this, you can work out all the id's of the instances that have been persisted.
If you need some information from each instance before proceeding then once you have that list of id's, it's possible to go through the WorkflowRuntime and use the GetWorkflow method to load up those instances and examine them. Once you have workflow id's you can use something like the StateMachineWorkflowInstance class to work out where you particular instances are up to.
Naturally, this might be more expensive than just storing off a list of id's and the "interesting information" elsewhere but you'd probably have to test with your scenario to work that out.
I built a simple sample of trying to do this kind of thing. It modes the idea of a traffic light that goes through a number of states;
There is then a little Windows Forms host application which will allow you to instantiate a number of these workflows and provide the events (red, orange, green) that drive them through their transitions. The Windows Forms app looks like this;
The way this works is that you click;
- "Kick off The Runtime"
- "Create New Workflow" (as many times as you want). This will add Guids to the listbox.
- "Red/Orange/Green" buttons to drive the instance id you have selected in the listbox through its transitions. The current state is indicated with a colour. When an instance gets to "green" it will disappear as that last transition causes the workflow to complete.
- At some point you can do "Unload Workflows and Runtime"
- You can then either start back at (1) where the Workflows that were outstanding should get reloaded or you can shut down the application and re-start it over again.
The project file is here for anyone to play with. All mistakes mine :-) These are RC1 bits.
Posted
Mon, Sep 11 2006 3:42 PM
by
mtaulty