I have a workflow that primarily consists of identical elements.
Each element is defined like this:

The workflow may simply stack these elements in a sequence, it may run them in parallel, it may have branching between them, etc. – total freedom for the workflow designer. The whole thing is hosted as a WCF service, but I would prefer not to rely on that, if at all possible.
The high level idea of this whole setup is the following:
- When the workflow starts, these elements start firing up, one after another, quickly skipping over the top condition branch. Completion of the previous element causes start of the next one – as defined in the workflow.
- At some point, when the condition
[B]is right, an element might take the bottom branch and become waiting for a WCF call. - Sooner or later, either all elements come to this kind of stop, or the workflow ends altogether.
What I need is to catch that moment when all elements stop to wait for WCF call.
At that point, I need to perform some calculations that will affect further flow of the workflow. Therefore, I need to catch that moment precisely.
Some notes:
- I guarantee that no WCF calls will come before I make those calculations. Therefore, possible race conditions connected to WCF calls are out of scope.
- I do not have an application that I control the control flow of. In other words, I am hosted in IIS, and therefore, am subject to restart without notice, and cannot setup timers, long-running loops, message pumps, and the like.
- I do not control the design of the workflow.
- However, I do totally control the design of the element. In fact, this element is actually a
NativeActivity(that’s why the diagram is from Visio 🙂 that I control the source code of. - I also control, to some extent, the hosting environment. That is, I can make modifications to the web application that the workflow is hosted in.
- The whole workflow is “attached” to a business object, and all elements have access to it.
The best way to do this is to create an extension that is a TrackingParticipant. This extension will receive all the tracking records in the Track method. Then when it receives the WorkflowInstanceStateRecord and the state is “Idle” you will know that the workflow is idle. Activities can access this extension to receive data from it or call methods on it as well.
This is the technique I used in the Introduction to State Machine Hands On Lab