Windows Workflow Foundation 3


Workflow Runtime Accepts HandleExternalEventActivity Events Out of Sequence


I am new to WWF and trying to model a simple call tracking application with a sequencial workflow. The first activity of the workflow is to wait for user input concerning the nature of the call (e.g. customer name).  The second activity waits for the closure of the call.  I have modelled this as a sequetial workflow with two activities.  The first activity is a HandleExternalEventActivity activity and handles the receipt of the customer information - Activity #1.  The second call is also a HandleExternalEventActivity activity and handles the closure of the call - Activity #2.  The behaviour that I am seeing is that the workflow engine allows for Activity #2 to be handled before Activity #1 has been handled.  Steps to reproduce:
Create a sequential workflow with two HandleExternalEventActivity activities.
Start an instance of the sequential workflow.
Raise the event needed for Activity #2
Raise the event needed for Activity #1
The workflow completes.
I would not have expected the workflow engine to allow Activity #2 to be handled before Activity #1.  I would think that the workflow engine should enforce the sequential nature of the defined workflow and throw exceptions or ignore events that arrive out of sequence.
Is this a bug, or I am doing something wrong, or is this the "As Designed" sequential workflow runtime characteristics.
Hi Andrew,
This is actually by design and expected as the behavior of a sequential workflow.  If you notice though, sequential workflow does preserve the sequence, despite the fact that the second event arrived first.  It will store it in the queue, but will not process it until that activity executes (the previous activity must complete first).
There are two recommended ways of achieving the scenario you're looking for.
First, you can use a State Machine Workflow.  The scenario you describe is exactly that - two states.  In state1, only message1 is valid, and an exception should be thrown if message 2 is received.  In state2, only message2 is valid.
Second, you can use correlation and Sequential Workflow as you have it modeled now.  You would make some modifications to your interface as follows:
[ExternalDataExchange][CorrelationParameter("InstanceId")]public interface IFoo{     [CorrelationInitializer]     event EventHandler<ExternalDataEventArgs> FirstEvent;
     event EventHandler<ExternalDataEventArgs> SecondEvent;}
Your first event would be deemed an "initializer," which means that until that event is received, no subsequent events mapped to that correlation will have queues created (and thus be unable to receive any messages).  When you add the CorrelationParameter and CorrelationInitializer attributes to your interface, you'll notice that your HandleExternalEvent activities will now require an additional property:  CorrelationToken.  This is an instance of an object that gets "Initialized" by the initializing event, and then "follower" events (SecondEvent in this case) will use this to determine if they are in scope.
You'll notice that after this modification, delivering the second event first will result in an exception because a queue has not been created for the second event at this point.
Thanks,Angel
I had a similair issue but with a state machine workflow (it wasn't a problem i'm just experimenting with workflows). I started a new workflow instance in state A. I then suspended the workflow instance and triggered 2 events (X and Y), both of which could be handled by state A. When i resumed the workflow instance event X moved the workflow into state B which couldn't handle event Y. I then triggered a third event (Z) that moved the workflow into state C which handled event Y and moved the workflow into state D. This behaviour could be really useful, but there might be cases where you don't want events triggered while in one state to be handled while in another state.
Andrew,
this is very strange indeed; I've tried to reproduce this in a small sample, but in my case Activity 1 run before Activity 2 if I fire the event 2 before the event 1; normally, event 2 is stored in a queue...
Do you use wwf beta 2.2 as I do ?
Serge Luca
Guidance, Belgium
blog : www.redwood.be
 
I am using Beta 2.2. Allow me to clarify . What I see happening is that when event #2 is triggered first before event #1, event #2 becomes queued so that as soon as Activity #1 completes, Activity #2 is executed immediately. From your previous post you state "normally, event 2 is stored in a queue". So is this queueing behaviour as-designed? I guess I would have expected the runtime to disallow events from being queued until the workflow arrived at the specific step for that event. Can a workflow be configured to disallow this type of thing from happening?
Andrew - the reason you are seeing this behavior is because your two HandleExternalEvents are right next to each other and the Runtime knows this.  If you did this with a StateMachineWorkflow instance - the firing of the second event would cause an exception because the workflow would not be able to receive those events.
 
In terms of the queueing system - it just means that the queues for both of those events is created by the time the workflow first becomes idle.
So are you saying that the only way for the runtime to enforce the proper sequencing of events is to use a state machine workflow?  I was hoping to stick with a sequential workflow.  For our specific requirements the sequential workflow seems to a better fit - for reasons other than this specific sequencing problem - see http://blogs.msdn.com/davegreen/archive/2005/10/20/483309.aspx.
The two activity example that I describe is a simplistic example for discussion and experimentation purposes.  Ultimately I can see our workflow comprised of 20 (or more) activities - I would hate to see the workflow engine eating and queueing events for event #20 before it even had a chance to eat event #1.
Well - it doesn't eat them - in my test - Event One fires before Event Two - so the messages are delivered in order.  There may be a way to stop this behavior with a SequentialWorkflow - but I don't know what it is.
If you used correlation  - then I believe the queues wouldn't get created until the correlationtoken was initalized - but I haven't testing that.
for the info, I have the same behavior if I put a code activity between the HandleExternal Events;
But personally I don't find this feature that bad...A smart queuing system... ;)
Serge Luca
Guidance, Belgium
blog : www.redwood.be
You mean you see handleexternalEvent #2 fire before handleexternalevent#1?
No; I see event 1 handled before event 2...
 
I think there might be some confusion with the original problem, let me clarify:
In our example, all the events are being generated outside of the workflow engine.  Since we are dealing with "HandleExternalEventActivity" activity types it is the responsibility of the host environment to somehow raise an event.  In my test app I have simple windows app with buttons, one button that raises an event that is coupled with activity #1 and another button that raises an event that is coupled with activity #2. 
At design time we couple the activity to an event declaration thru the "HandleExternalEventActivity.InterfaceType" and "HandleExternalEventActivity.EventName" properties.  The issue that I have with the workflow runtime is that I am able to raise event #2 without getting yelled at by the runtime (i.e. exception thrown) before having raised event #1.  Moreover, if I push button #2, which raises event #2, the event gets queued and as soon as activity #1 is completed, activity #2 is automatically and immediately "triggered" (with the apparently queued out of sequence event from before).
Is this really the "As Designed" behaviour for sequential workflows?
Andrew, this is exactly what I've understood and tested (but in a console app).
I don't know if the current behavior is "by design"; if the workflow was a state machine, it's normal that you would get an exception, but since your are using a sequential workflow and that the listener for event 2 is "in the pipe" if could make sense that you don't get any exception here.
Only a member of the Workflow team could clarify this...
Serge Luca
Guidance, Belgium
blog : www.redwood.be
 
 
Thanks a bunch for all your help, I very much appreciate it.  I shall wait and see if someone from the workflow team might be able to shed some more light on this.
Hi Andrew,
This is actually by design and expected as the behavior of a sequential workflow.  If you notice though, sequential workflow does preserve the sequence, despite the fact that the second event arrived first.  It will store it in the queue, but will not process it until that activity executes (the previous activity must complete first).
There are two recommended ways of achieving the scenario you're looking for.
First, you can use a State Machine Workflow.  The scenario you describe is exactly that - two states.  In state1, only message1 is valid, and an exception should be thrown if message 2 is received.  In state2, only message2 is valid.
Second, you can use correlation and Sequential Workflow as you have it modeled now.  You would make some modifications to your interface as follows:
[ExternalDataExchange][CorrelationParameter("InstanceId")]public interface IFoo{     [CorrelationInitializer]     event EventHandler<ExternalDataEventArgs> FirstEvent;
     event EventHandler<ExternalDataEventArgs> SecondEvent;}
Your first event would be deemed an "initializer," which means that until that event is received, no subsequent events mapped to that correlation will have queues created (and thus be unable to receive any messages).  When you add the CorrelationParameter and CorrelationInitializer attributes to your interface, you'll notice that your HandleExternalEvent activities will now require an additional property:  CorrelationToken.  This is an instance of an object that gets "Initialized" by the initializing event, and then "follower" events (SecondEvent in this case) will use this to determine if they are in scope.
You'll notice that after this modification, delivering the second event first will result in an exception because a queue has not been created for the second event at this point.
Thanks,Angel
I had a similair issue but with a state machine workflow (it wasn't a problem i'm just experimenting with workflows). I started a new workflow instance in state A. I then suspended the workflow instance and triggered 2 events (X and Y), both of which could be handled by state A. When i resumed the workflow instance event X moved the workflow into state B which couldn't handle event Y. I then triggered a third event (Z) that moved the workflow into state C which handled event Y and moved the workflow into state D. This behaviour could be really useful, but there might be cases where you don't want events triggered while in one state to be handled while in another state.

Related Links

Dynamic Workflow Creation
ApplyworkflowChanges takes long time and some time crashes the application.
CLR20r3 Error when i run exe file (C#)
Process is terminated due to StackOverflowException
HandleExternalEvent: event filter / correlation
SqlTrackingService & User Events
How to change the sendemail activity property at run time?
Question on Queue Management
Load rules in the Designer Rehosting demo
IExtendedUIService must be installed
Does WF support transactions?
After wf receives external event, the host never sees any more tracking events
How to implement Unit test in a Sequential workflow
data exchange between workflow activities
While() activity a cpu hog
Share large data between workflow and application

Categories

MSDN
Apps for Office and Sh...
.NET Framework
Visual Studio Design a...
Internet Explorer Deve...
Microsoft Robotics
Feedback and Discussions
Open Specifications
Silverlight
Archived Forums W
In-App Advertising (Ad...
Archived Forums
Microsoft Partner Center
Internet of Things
C++ Standards, Extensi...
Visual Studio Tools fo...
Windows Desktop Debugging
Windows Desktop Search...
Windows Desktop Winsoc...
General Office Develop...
Office 365 for Developers
SharePoint Legacy Vers...
Azure Multi-Factor Aut...
Azure Mobile Apps
Microsoft Azure Site R...
Azure Backup
Azure Scheduler
Azure Mobile Engagement
Cognitive Services
Team Foundation Server...
The Architect Role
BizTalk Server General
BizTalk Server Adapter...
WCF Data Services
Internet Explorer Web ...
SQL Server Integration...
SQL Server Analysis Se...
Transact-SQL
.NET Framework inside ...
SQL Service Broker
Microsoft Drivers for ...
SQL Server Search
SQL Server PowerPivot ...
Standard 7: Components...
Standard 7: Tools
Windows Embedded Compa...
SQL Server 2012 Master...
Windows Forms Data Con...
Bing Maps: Map Control...
Windows Live ID: Devel...
MSDN Subscriptions Fee...
Orchard –Discussions
Bing Maps WPF, WP7/8/8...
Windows Protocols
Exchange Server Protocols
Visio General Question...
Silverlight Installati...
Getting Started with S...
Programming Silverligh...
Visual Studio & Silver...
Report a Silverlight Bug
WCF RIA Services with ...
Expression Encoder
Retired InfoPath Forms...
Retired SharePoint Ent...
ADO.NET Entity Framewo...
Archived: Software Tes...
ASMX Web Services and ...
Azure Troubleshooting,...
Azure Startups
Dryad, DSC, and DryadL...
HD DVD Interactivity A...
Face Tracking – Kinect...
Model-Based Testing wi...
Office Development wit...
Search Server: Federation
Silverlight (formerly ...
Silverlight (formerly ...
SQL Server 2014 Self-S...
Team Foundation Server...
Transactions Programming
Using Visual Round Tri...
TFS Deployment to Azure
Visual Basic IDE
Visual Basic Language
Visual Basic Power Packs
Visual C# Express Edition
Visual C++ IDE
Visual Studio Performa...
Visual Studio Team Sys...
Visual Studio Team Sys...
Visual Studio WPF/SL D...
Windows XP Wireless SDK
Windows Phone push not...

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile