R – delay activity in event handling scope activity – windows workflow sharepoint

delaysharepointworkflowworkflow-foundation

I am trying to create a following scenario:

  • a task gets assigned to the user to complete
  • a task get created for the manager to reassign the user task if necessary (don't ask, they wanted it this way)
  • an email reminder neeeds to be sent when the task is nearing a due date

So, I thought of using EventHandlingScope for this:

  • I am listening for a task change on the main branch of eventhandlingscope activity,
  • listening to reassign task change in event driven branch – and if reassign task gets activated, reassign the first task to the user specified
  • in another event driven branch use a delay activity and check periodically if user assigned task is nearing a due date and send an email reminder

So, I though eventhandlingscope would be good for this, and it mostly is, except for the problem with the DelayActivity.

If I put a delay activity in one of the Event Handlers branches it fires once, but not more.
Whereas if I put an onTaskChange activity there it fires everytime somebody changes that task.

So, is this the expected behaviour? Why doesn't DelayActivity loop?
How could I do this differently? My thought is with a CAG, but this looks a bit more complex…

Update: the problem with CAG is that the whole thing blocks until delay activity fires, even if the onChange event fired. This makes sense, but makes it a bit trickier to use.

Update2: I've reworded the text to make it hopefully clearer

Best Answer

The Solution

The fundemental activity arrangement that solves this problem is a WhileActivity containing a ListenActivity.

The listen activity is given 3 EventDrivenActivity branches. On the first is your "User Task Completed" branch, the second is the "Manager Changed the assigned user" branch and the third contains a DelayActivity followed by your emailing logic.

In a listen activity any of the branches can complete the Listen activity and when they do the other activities in the Listen activity will be canceled.

You will need to ensure the the "User Task Completed" sequence sets some value that can be tested by the while loop such that the while loop exits when a user completes a task.

When a branch other than the "User Task Completed" branch is responsible for completing the the ListenActivity workflow will loop back to the ListenActivity and re-execute all 3 event driven activities including the one containing the DelayActivity.

Note that this is slightly different from the EventHandlingScope approach because the "listen for user task completed" will get canceled and re-executed whereas with the EventHandlingScope that wouldn't happen. IMO this a better arrangement since it means that the user that was currently selected to do the task at the start of the Listen activity is guaranteed to be unchanged at the end (because if it is changed the whole activity is discarded and a new one started).

Why the Delay only fired once in the EventHandlingScope

Effectively what you had set up is a scope that is listening for two events. One was your managers change assigned user event, the other was a "timer fired event".

Now the way its described in the documentation it sounds like some loop is involved as if once one of these activities completes they are restarted. However its not quite like that, it actually just continues to listen for the original event and will re-run the contents if another such event is fired.

In the case of the DelayActivity there is some internal "timer fired event" that is being listened to. When the Delay is first entered the timeout is setup so that the timer will fire at the appropriate time, it then listens for that event. Once it has fired the scope returns to listening to a "timer fired event", however, there is no re-running of the initial code that setup the timeout hence no other "timer fired event" is forth coming.