The chapter re-enforces the concepts already introduced and gives the process the name of Activity Automaton. There are a number of ideas/concepts introduced and a fair amount of example to code (I like to actually write and test the code myself). The chapter is good and in theory you could probably start the book here. It does suffer from an ordering problem, i.e. it will describe or show some code that is introduced later in the chapter. E.g. one sample shows an Activity using a TimerService. The TimeService is show a couple of pages later. Nothing terrible about that but there is no reason why the TimerService couldn’t have been show first. There was one example that annoyed me, where the authors ask you to implement n workflow XOML using a property mechanism that won’t be introduced until chapter 7! Anyway these are tiny points in another excellent chapter.
Scheduling – The schedule dispatches Work Items one at a time from a FIFI queue (not to be confused with the WF Program queues). A Work Item is a delegate pointing to a WF activity in a specific program instance.
The basic Activity Automaton consists of an activity going through the following phases – Inialized -> Executing -> Closed
The Scheduler moves an activity into Executing and the WF Program processes the activity.
ActivityExecutionContext – available to the "Events" or phases and can be considered as the provider/gateway to services. It is disposable between calls so don’t cache it!
Using base.Invoke to create a bookmark and ask for resumption. This yields control back to the Scheduler for continuation at some point (hopefully soon).
NB. If you queue an item in the program queue and the runtime finishes then the queue must be passiavated (persisted to store) or an exception is raised.
WF Program Queues are on a per program instance so a program queue called myQueue can exist multiple times but
the queue is not shared across program instances.
Wait Activity – An activity (using a TimerService) that creates a queue via a specific id. The activity then "waits"
for the service to queue (EnqueueItem) the timer tick and it wakes up, does what it needs to do and deletes the queue.
Passing the runtime into a service in order to hide more of the implementation, i.e. hiding the interaction with the
CreateWorkflows calls the initialize of all the contained activities, only after all of them been called
(and returned) does the worflow start in earnest. Remember no ExecutionContext exists during Initialize.
A good use is to create workflow queues, and remove them in Unintialize.
Unitialize – clean up resources allocated in Initialize
OnClosed – clean up resources allocated during the running of the activity
Closed state – before the workflow delivers a work item to an activity it checks the state of the activity. If the activity is closed the item is simply discarded.
DataBound properties exist outside of a running activity, e.g. a bit like maintaining state even after an activity has closed.
Assume that every work item is run on a different thread, i.e. don’t rely on TLS (Thread Local Storage).
One CLR thread per WF Program.
Synchronization – Synchronization of activities can be achieved using the SynchronizationScopeActivity which uses a common key (or SynchronizationHandles) to denote those activities that should be run one at a time. If any acivities share a handle (including their nested/child activities) then they will be considered as requiring synchronization and will not be run at the same time (pseudo concurrency).