Event-driven execution in .NET 4.0 with the Pick activity

.NET 4.0 and WF 4.0 include a new event-driven control flow activity called Pick that takes the place of the original Listen activity in .NET 3.x. Whereas the branches in the Listen activity may be triggered only by activities that implement the IEventActivity interface, the branches in a Pick activity may be triggered by any activity.

Listen activity

Picture: Listen activity in .NET 3.x

In WF 4.0, the Pick activity provides event-based control flow modeling.  Pick contains multiple branches, where each branch waits for a particular event to occur before running.  Branches are event-driven and the event that occurs causes the corresponding branch to run;  all other branches cancel and stop listening for events.  Each branch is a PickBranch activity, and each PickBranch activity consists of a trigger and an action.  The completion of a trigger equates to that event firing.

The Pick activity addresses several main scenarios described below.


The most common scenario (among forum posters) is to implement a timeout using Pick.  For example, in an expense approval process, the manager should approve or reject the expense report within a week of submission. If she fails to do so, then the system sends her a reminder email. Pick can be used to timebox the receipt of the manager’s response.


In the above example, the Receive activity and the Delay activity run simultaneously.  The one that finishes first will cause the other branch to cancel.

Choosing between multiple events

Another common scenario is choosing between multiple events.  For example, in an expense report approval process, the manager may approve or reject the expense report. The expected behavior of the following workflow is that one of the Pick triggers will win, and the rest will be cancelled.


Asynchronous logic and composition in the trigger

An approval process may require two departments both to approve before it’s approved, while either one may reject it.


In cases like this where the triggers contain asynchronous logic, it’s important to keep in mind that the branch that wins is the branch whose trigger completes first.  The branch whose trigger receives the first message is not necessarily the branch that wins.


Now that you have a basic understanding…

Happy exploring the Pick activity.  Post your questions to the forum, or leave me a comment here.


Xiaowen Xin
Program Manager (WF/WCF)