I’m working on migrating our old workflow system to WF 4. In our current setup, we have this cool feature where we can stop whatever activity is running and jump back to a decision node when new information comes in.
Here’s my situation: I have a workflow that starts and uses a FlowSwitch to pick which path to take. Let’s say it chooses path B2 and sits there waiting for user input with a bookmark.
----B1----\
| \
/\ \
Start ---->(B2)---->End
^ \/ / |
| | / |
| ----B3--/ |
| |
|------------------|
But then some external data arrives that changes everything. I need to cancel B2 and go back to the FlowSwitch so it can pick a new path based on this fresh data.
I’m thinking maybe I could use a Parallel activity. One branch would handle the main workflow stuff, and the other branch would listen for external data. But if the listening branch gets data, how do I actually cancel what’s happening in the main branch and make it restart from the FlowSwitch?
Is this the right approach or am I overthinking it? I’m pretty new to WF4 so maybe there’s an easier way to do this kind of thing.
the parallel approach is probably overkill. try a custom activity that inherits from NativeActivity and overrides the cancel method. when external data comes in, force cancel the current bookmark and reset your flowswitch variables. i used a while loop wrapper around everything - it keeps looping until there’s no interruptions. hacky but it works.
Yeah, classic workflow interruption problem. I’ve hit this before with approval systems that needed priority overrides.
Your Parallel approach works, but there’s a cleaner way. Use CancellationToken with custom activities.
Set up a CancellationTokenSource at the root level. Pass this token to all activities, especially ones waiting for user input. When external data comes in, cancel the current operation and restart from the beginning.
Here’s what worked for me: create a custom activity that wraps your FlowSwitch logic. This activity monitors for external data changes and restarts itself when needed. Inside the wrapper, use a while loop that runs until the workflow completes without interruption.
For the external data listener, I implement it as a separate service that talks to the workflow through shared context or workflow extensions. New data arrives, signal cancellation, update the decision variables.
Tricky part is maintaining state between restarts. Persist the workflow variables that determine which FlowSwitch path to take. WF4 handles most of this with persistence, but make sure your decision variables are serializable.
One gotcha I hit: make sure bookmark activities handle cancellation gracefully. Otherwise you’ll get zombie bookmarks that never clean up.