<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Matt W's Windows Workflow Place : patterns</title><link>http://blogs.msdn.com/mwinkle/archive/tags/patterns/default.aspx</link><description>Tags: patterns</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Advanced Workflow Service Talk (Demo 4 of 4)</title><link>http://blogs.msdn.com/mwinkle/archive/2008/08/11/advanced-workflow-service-talk-demo-4-of-4.aspx</link><pubDate>Mon, 11 Aug 2008 18:52:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8848313</guid><dc:creator>mwinkle</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/8848313.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=8848313</wfw:commentRss><description>&lt;p&gt;When we start doing this two way style of messaging, we now open up to start modeling some interesting business problems.&amp;#160; In the previous post, you'll note that I did not include the code, because I mentioned we needed to be more clever in scenarios where we listen in parallel.&amp;#160; &lt;/p&gt;  &lt;p&gt;First, a brief diversion into how the Receive activity works.&amp;#160; Everybody remembers the workflow queues, the technology that underlies all communication between a host and a workflow instance.&amp;#160; The Receive activity works by creating a queue that the WorkflowServiceHost (specifically the WorkflowOperationInvoker) will use to send the message received off the wire into the workflow.&amp;#160; Now, the Receive activity normally just creates a queue that is named the same as the operation the Receive activity is bound to.&amp;#160; However, if we have two Receive activities listening for the same operation at the same time, no longer is a single queue useful to route responses back as we want to route to the correct Receive activity instance.&amp;#160; &lt;/p&gt;  &lt;p&gt;There is property on the Receive activity called ContextToken.&amp;#160; Normally this is null in the simple case.&amp;#160; However, when we want our Receive activity to operate in parallel, we need to indicate that it needs to be smarter when it creates a queue.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServiceTalkDemo4of4_9005/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="227" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServiceTalkDemo4of4_9005/image_thumb.png" width="409" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;By setting this property (you can just type in a name, and then select the common owner all of the parallel receive's share.&amp;#160; This will cause the Receive activity to create a queue named [OperationName] +[ConversationId], the conversation ID takes the form of a GUID, and is the second element inside a context token.&amp;#160; &lt;/p&gt;  &lt;p&gt;The sample that I show for this talk is simply the &lt;a href="http://msdn.microsoft.com/en-us/library/bb410775.aspx"&gt;conversations sample inside the SDK&lt;/a&gt;.&amp;#160; This is the sample to check out to understand all sorts of interesting ways to use the context tokens to model your processes.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb410775.aspx"&gt;&lt;img alt="Conversations Sample Architecture" src="http://i.msdn.microsoft.com/Bb410775.7f198cc1-b77a-4460-a007-4ac0ac91a109(en-us,VS.90).gif" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Now, there are two conversation patterns here.&amp;#160; One is the one shown above, which I refer to as an &lt;em&gt;n&lt;/em&gt;-party conversation where &lt;em&gt;n&lt;/em&gt; is fixed at design time.&amp;#160; We can accomplish this with the parallel activity.&amp;#160; The other is where &lt;em&gt;n&lt;/em&gt; is arbitrary (imagine you send out to business partners stored in the database).&amp;#160; The way to do this is to use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.activities.replicatoractivity.aspx"&gt;Replicator&lt;/a&gt; activity.&amp;#160; The Replicator is a little known gem shipped in 3.0 that essentially gives you &amp;quot;ForEach&amp;quot; semantics.&amp;#160; But, by flipping the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.activities.replicatoractivity.executiontype.aspx"&gt;ExecutionType&lt;/a&gt; switch to parallel, I now get the behavior of a parallel, but operating with an arbitrary &lt;em&gt;n&lt;/em&gt; branches. &lt;/p&gt;  &lt;p&gt;So, in order to enable conversations, we need to tell our receive activity to be a little smarter about how it generates its queue name, and then we simply follow the duplex pattern we discussed in the last &lt;a href="http://blogs.msdn.com/mwinkle/archive/2008/08/06/advanced-workflow-services-talk-demo-2-of-4.aspx#comments"&gt;two&lt;/a&gt; &lt;a href="http://blogs.msdn.com/mwinkle/archive/2008/08/07/advanced-workflow-services-talk-demo-3-of-4.aspx"&gt;posts&lt;/a&gt;.&amp;#160; Once we do that, we're in good shape to start modeling some more interesting communication patterns between multiple parties.&amp;#160; &lt;/p&gt;  &lt;h3&gt;Where can we go from here? &lt;/h3&gt;  &lt;p&gt;   &lt;br /&gt;We can just make the patterns more interesting.&amp;#160; One interesting one would be the combination of the long running work with cancellation and a &lt;a href="http://blogs.msdn.com/mwinkle/archive/2007/06/27/implementing-the-n-of-m-pattern-in-wf.aspx"&gt;Voting activity&lt;/a&gt; in order to coordinate the responses and allow for progress to be made when some of the branches complete (if I have 3 yes votes, I can proceed).&amp;#160; The power of building composite activities is that it gives me a uniform programming model (and a single threaded one to boot) in order to handle the coordination of different units of work.&amp;#160; Get out there and write some workflows :-) &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8848313" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mwinkle/archive/tags/wf/default.aspx">wf</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/Orcas/default.aspx">Orcas</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/WCF/default.aspx">WCF</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/patterns/default.aspx">patterns</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/presentations/default.aspx">presentations</category></item><item><title>N of M Question (Why Use ActivityExecutionContextManager?)</title><link>http://blogs.msdn.com/mwinkle/archive/2007/07/09/n-of-m-question-why-use-activityexecutioncontextmanager.aspx</link><pubDate>Mon, 09 Jul 2007 19:32:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3783390</guid><dc:creator>mwinkle</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/3783390.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=3783390</wfw:commentRss><description>&lt;p&gt;In &lt;a href="http://blogs.msdn.com/mwinkle/archive/2007/06/27/implementing-the-n-of-m-pattern-in-wf.aspx"&gt;this post&lt;/a&gt;, mstiefel &amp;nbsp;asked the following:&lt;/p&gt; &lt;blockquote&gt; &lt;h6&gt;&lt;a href="http://blogs.msdn.com/mwinkle/archive/2007/06/27/implementing-the-n-of-m-pattern-in-wf.aspx#3735848"&gt;#&lt;/a&gt; re: Implementing the N of M Pattern in WF&lt;a&gt;&lt;/a&gt;&lt;/h6&gt; &lt;p&gt;Since you are not looping, do you have to use the ActivityExecutionContextManager to generate a new context for the child activities? Couldn't you use the context passed into the Execute method?  &lt;p&gt;Friday, July 06, 2007 7:54 PM by &lt;a href="http://www.reliablesoftware.com"&gt;mstiefel&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;If I were creating a parallel activity, and simply wanted to execute a number of distinct child activities, I would just use the passed in context as you suggest to schedule execution of each of the activities.&amp;nbsp; The difference here&amp;nbsp;is subtle, and that is I don't have distinct child activities, I have one child activity which I need to clone &lt;em&gt;m&lt;/em&gt;&amp;nbsp;times and execute those cloned children separately.&amp;nbsp; The need to create the context is so that each one of those clones maintains it's own execution context, what variables are where, who is in what state, etc.&amp;nbsp; This is important while executing, and while after completion in the need where I want to compensate for the individual activities.&lt;/p&gt; &lt;p&gt;This line&lt;/p&gt;&lt;pre class="csharpcode"&gt;ActivityExecutionContext newContext = aecm.CreateExecutionContext(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities[0]);&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;is what will cause the activity to be cloned, allowing me to schedule the execution of the clone, and not the template activity (which, incidentally, will never be scheduled, leaving me with &lt;em&gt;m+1&lt;/em&gt;&amp;nbsp; copies of the activity.&amp;nbsp; This is the same behavior that I get in a While or a Replicator (or the CAG, depending upon how it is configured).&amp;nbsp; A state machine workflow will do a similar thing as I may re-enter a state multiple times.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;If, instead of allowing a user to specify the list of approvers and dynamically creating the activities, I designed it so that a user would have to drop and configure an activity for each approval (similar to the parallel activity), I would have used code like this:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Code to schedule distinct activities in parallel, aka code similar to the parallel activity&lt;/span&gt;
&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Activity activity &lt;span class="kwrd"&gt;in&lt;/span&gt; ChildActivities)
        {
            &lt;span class="rem"&gt;// i is some counter I use to track how many branches there are so I know when&lt;/span&gt;
            &lt;span class="rem"&gt;// I am done&lt;/span&gt;
            i++;
            &lt;span class="rem"&gt;// I'm interested in what happens when this guy closes.&lt;/span&gt;
            activity.RegisterForStatusChange(Activity.ClosedEvent, &lt;span class="kwrd"&gt;this&lt;/span&gt;);
            executionContext.ExecuteActivity(activity);
        }
        &lt;span class="kwrd"&gt;return&lt;/span&gt; ActivityExecutionStatus.Executing;
}
&lt;/pre&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3783390" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mwinkle/archive/tags/wf/default.aspx">wf</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/patterns/default.aspx">patterns</category></item><item><title>Implementing the N of M Pattern in WF</title><link>http://blogs.msdn.com/mwinkle/archive/2007/06/27/implementing-the-n-of-m-pattern-in-wf.aspx</link><pubDate>Wed, 27 Jun 2007 03:38:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3556624</guid><dc:creator>mwinkle</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/3556624.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=3556624</wfw:commentRss><description>&lt;p&gt;The second in my series of alternate execution patterns (&lt;a href="http://blogs.msdn.com/mwinkle/archive/2007/05/24/different-execution-patterns-with-wf-or-going-beyond-sequential-and-state-machine.aspx"&gt;part 1&lt;/a&gt;)  &lt;p&gt;I recently worked with a customer who was implementing what I would call a "basic" human workflow system. It tracked approvals, rejections and managed things as they moved through a customizable process. It's easy to build workflows like this with an Approval activity, but they wanted to implement a pattern that's not directly supported out of the box. This pattern, which I have taken to calling "n of m", is also referred to as a "&lt;a href="http://www.workflowpatterns.com/patterns/control/new/wcp35.php"&gt;Canceling partial join for multiple instances&lt;/a&gt;" in the van der Aalst taxonomy. &lt;p&gt;The basic description of this pattern is that we start m concurrent actions, and when some subset of those, n, complete, we can move on in our process and cancel the other concurrent actions. A common scenario for this is where I want to send a document for approval to 5 people, and when 3 of them have approved it, I can move on. This comes up frequently in human or task-based workflows. There are a couple of "business" questions which have to be answered as well, the implementation can support any set of answers for this: &lt;ul&gt; &lt;li&gt;What happens if an individual rejects? Does this stop the whole group from completing, or is it simply noted as a "no" vote? &lt;li&gt;How should delegation be handled? Some business want this to break out from the approval process at this point.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The first approach the customer took was to use the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.activities.conditionedactivitygroup.aspx"&gt;ConditionedActivityGroup&lt;/a&gt; (CAG). The CAG is probably one of the most sophisticated out of the box activities that we ship in WF today, and it does give you a lot of control. It also gives you the ability to set the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.activities.conditionedactivitygroup.untilcondition.aspx"&gt;Until&lt;/a&gt; condition which would allow us to specify the condition that the CAG could complete, and the others would be cancelled (see &lt;a href="http://msdn2.microsoft.com/en-us/library/ms741710.aspx"&gt;Using ConditionedActivityGroup&lt;/a&gt;) &lt;p&gt;&lt;img height="268" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/ImplementingtheNofMPatterninWF_F7F8/clip_image001_1.png" width="246" align="right"&gt; &lt;p&gt;ConditionedActivityGroup &lt;p&gt;What are pros and cons of this approach: &lt;p&gt;Pros &lt;ul&gt; &lt;li&gt;Out of the box activity, take it and go &lt;li&gt;Focus on approval activity &lt;li&gt;Possibly execute same branch multiple times&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Cons &lt;ul&gt; &lt;li&gt;Rules get complex ( what happens if the individual rejections causes everything to stop) &lt;li&gt;I need to repeat the same activity multiple times (especially in this case, it's an approval, we know what activity needs to be in the loop) &lt;li&gt;I can't control what else a developer may put in the CAG &lt;li&gt;We may want to execute on some set of approvers that we don't know at design time, imagine an application where one of the steps is defining the list of approvers for the next step. The CAG would make that kind of thing tricky.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;This led us to the decision to create a composite activity that would model this pattern of execution. Here are the steps we went through: &lt;h3&gt;Build the Approval activity&lt;/h3&gt; &lt;p&gt;The first thing we needed was the approval activity. Since we know this is going to eventually have some complex logic, we decided to take the basic approach of inheriting from SequenceActivity and composing our approval activity out of other activities (sending email, waiting on notification, handling timeouts, etc.). We quickly mocked up this activity to have an "Approver" property, a property for a timeout (which will go away in the real version, but is useful to put some delays into the process. We also added some code activities which Console.WriteLine 'd some information out so we knew which one was executing. We can come back to this later and make it arbitrarily complex. We also added the cancel handler so that we can catch when this activity is canceled (and send out a disregard email, clean up the task list ,etc). Implementing ICompensatableActivity may also be a good idea so that we can play around with compensation if we want to (note, that we will only compensate the closed activities, not the ones marked as canceled). &lt;p&gt;&lt;img height="265" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/ImplementingtheNofMPatterninWF_F7F8/clip_image002.png" width="452"&gt; &lt;p&gt;Properties of the Approval Activity &lt;p&gt;&lt;img height="321" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/ImplementingtheNofMPatterninWF_F7F8/clip_image003.png" width="222"&gt; &lt;p&gt;Placing the Approval Activity inside our NofM activity. &lt;h3&gt;What does the execution pattern look like?&lt;/h3&gt; &lt;p&gt;Now that we have our approval activity, we need to determine how this new activity is going to execute. This will be the guide that we use to implement the execution behavior. There are a couple of steps this will follow &lt;ol&gt; &lt;li&gt;Schedule the approval's to occur in parallel, one per each approver submitted as one of the properties &lt;li&gt;Wait for each of those to finish. &lt;li&gt;When one finishes, check to see if the condition to move onward is satisfied (in this case, we increment a counter towards a "number of approvers required" variable. &lt;li&gt;If we have not met the criteria, we keep on going. [we'll come back to this, as we'll need to figure out what to do if this is the last one and we still haven't met all of the criteria.] &lt;li&gt;If we have met the criteria, we need to cancel the other running activities (they don't need to make a decision any more).&lt;/li&gt; &lt;li&gt;Implement the easy part of this (scheduling the approvals to occur in parallel)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I say this is the easy part as this is documented in a number of places, including&lt;a href="http://www.amazon.com/Essential-Workflow-Foundation-Microsoft-Development/dp/0321399838/ref=pd_bbs_sr_1/105-8140718-5930861?ie=UTF8&amp;amp;s=books&amp;amp;qid=1179959181&amp;amp;sr=8-1"&gt; Bob and Dharma's book&lt;/a&gt;. The only trickery occurring here is that we need to clone the template activity, that is the approval activity that we placed inside this activity before we started working on it. This is a topic discussed in Nate's now &lt;a href="http://blogs.msdn.com/advancedworkflow/archive/2006/03/21/557121.aspx"&gt;defunct blog&lt;/a&gt;.&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
    {
        &lt;span class="rem"&gt;// here's what we need to do.&lt;/span&gt;
        &lt;span class="rem"&gt;// 1.&amp;gt; Schedule these for execution, subscribe to when they are complete&lt;/span&gt;
        &lt;span class="rem"&gt;// 2.&amp;gt; When one completes, check if rejection, if so, barf&lt;/span&gt;
        &lt;span class="rem"&gt;// 3.&amp;gt; If approve, increment the approval counter and compare to above&lt;/span&gt;
        &lt;span class="rem"&gt;// 4.&amp;gt; If reroute, cancel the currently executing branches.&lt;/span&gt;
        ActivityExecutionContextManager aecm = executionContext.ExecutionContextManager;
        &lt;span class="kwrd"&gt;int&lt;/span&gt; i = 1;
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; approver &lt;span class="kwrd"&gt;in&lt;/span&gt; Approvers)
        {
            &lt;span class="rem"&gt;// this will start each one up.&lt;/span&gt;
            ActivityExecutionContext newContext = aecm.CreateExecutionContext(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities[0]);
            GetApproval ga = newContext.Activity &lt;span class="kwrd"&gt;as&lt;/span&gt; GetApproval;
            ga.AssignedTo = approver;
            &lt;span class="rem"&gt;// this is just here so we can get some delay and "long running ness" to the&lt;/span&gt;
            &lt;span class="rem"&gt;// demo&lt;/span&gt;
            ga.MyProperty = &lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(0, 0, 3 * i);
            i++;
            &lt;span class="rem"&gt;// I'm interested in what happens when this guy closes.&lt;/span&gt;
            newContext.Activity.RegisterForStatusChange(Activity.ClosedEvent, &lt;span class="kwrd"&gt;this&lt;/span&gt;);
            newContext.ExecuteActivity(newContext.Activity);
        }
        &lt;span class="kwrd"&gt;return&lt;/span&gt; ActivityExecutionStatus.Executing;
    }
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Code in the execute method
&lt;p&gt;One thing that we're doing here is &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.componentmodel.activity.registerforstatuschange.aspx"&gt;RegisterForStatusChange()&lt;/a&gt; This is a friendly little method that will allow me to register for a status change event (thus it is very well named). This is a property of Activity, and I can register for different activity events, like &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.componentmodel.activity.closedevent.aspx"&gt;Activity.ClosedEvent&lt;/a&gt; or &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.componentmodel.activity.cancelingevent.aspx"&gt;Activity.CancelingEvent&lt;/a&gt;. On my NofM activity, I implment &lt;a href="http://msdn2.microsoft.com/en-us/library/aa480200.aspx"&gt;IActivityEventListener&lt;/a&gt; of type &lt;a href="http://msdn2.microsoft.com/en-us/library/aa480200.aspx"&gt;ActivityExecutionStatusChangedEvent&lt;/a&gt; (check out &lt;a href="http://msdn2.microsoft.com/en-us/library/aa480200.aspx"&gt;this article&lt;/a&gt; as to what that does and why). This causes me to implement OnEvent which since it comes from a generic interface is now strongly typed to accept the right type of event arguments in. That's always a neat trick that causes me to be thankful for generics. That's going to lead us to the next part.
&lt;h3&gt;Implement what happens when one of the activities complete&lt;/h3&gt;
&lt;p&gt;Now we're getting to the fun part of how we handle what happens when one of these approval activities return. For the sake of keeping this somewhat brief, I'm going to work off the assumption that a rejection does not adversely affect the outcome, it is simply one less person who will vote for approval. We can certainly get more sophisticated, but that is not the point of this post! ActivityExecutionStatusChangedEventArgs has a very nice Activity property which will return the Activity which is the one that caused the event. This let's us find out what happened, what the decision was, who it was assigned to, etc. I'm going to start by putting the code for my method in here and then we'll walk through the different pieces and parts.&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnEvent(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ActivityExecutionStatusChangedEventArgs e)
{
    ActivityExecutionContext context = sender &lt;span class="kwrd"&gt;as&lt;/span&gt; ActivityExecutionContext;
    &lt;span class="rem"&gt;// I don't need to listen any more&lt;/span&gt;
    e.Activity.UnregisterForStatusChange(Activity.ClosedEvent, &lt;span class="kwrd"&gt;this&lt;/span&gt;);
    numProcessed++;
    GetApproval ga = e.Activity &lt;span class="kwrd"&gt;as&lt;/span&gt; GetApproval;
    Console.WriteLine(&lt;span class="str"&gt;"Now we have gotten the result from {0} with result {1}"&lt;/span&gt;, ga.AssignedTo, ga.Result.ToString());
    &lt;span class="rem"&gt;// here's where we can have some additional reasoning about why we quit&lt;/span&gt;
    &lt;span class="rem"&gt;// this is where all the "rejected cancels everyone" logic could live.&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (ga.Result == TypeOfResult.Approved)
        numApproved++;
    &lt;span class="rem"&gt;// close out the activity&lt;/span&gt;
    context.ExecutionContextManager.CompleteExecutionContext(context.ExecutionContextManager.GetExecutionContext(e.Activity));
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!approvalsCompleted  &amp;amp;&amp;amp; (numApproved &amp;gt;= NumRequired))
    {
        &lt;span class="rem"&gt;// we are done!, we only need to cancel all executing activities once&lt;/span&gt;
        approvalsCompleted = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Activity a &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetDynamicActivities(&lt;span class="kwrd"&gt;this&lt;/span&gt;.EnabledActivities[0]))
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (a.ExecutionStatus == ActivityExecutionStatus.Executing)
                context.ExecutionContextManager.GetExecutionContext(a).CancelActivity(a);
    }
    &lt;span class="rem"&gt;// are we really done with everything? we have to check so that all of the &lt;/span&gt;
    &lt;span class="rem"&gt;// canceling activities have finished cancelling&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (numProcessed == numRequested)
        context.CloseActivity();  
}
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Code from "OnEvent"
&lt;p&gt;The steps here, in English
&lt;ul&gt;
&lt;li&gt;UnregisterForStatusChange - we're done listening.
&lt;li&gt;Increment the number of activities which have closed (this will be used to figure out if we are done)
&lt;li&gt;Write out to the console for the sake of sanity
&lt;li&gt;If we've been approved, increment the counter tracking how many approvals we have
&lt;li&gt;Use the ExecutionContextManager to &lt;a href="http://msdn2.microsoft.com/en-us/library/ms592884.aspx"&gt;CompleteExecutionContext&lt;/a&gt;, this marks the execution context we created for the activity done.
&lt;li&gt;Now let's check if we have the right number of approvals, if we do, mark a flag so we know we're done worrying about approves and rejects and then proceed to cancel the activities. CancelActivity. &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.componentmodel.activityexecutioncontext.cancelactivity.aspx"&gt;CancelActivity&lt;/a&gt; schedules the cancellation, it is possible that this is not a synchronous thing (we can go idle waiting for a cancellation confirmation, for instance.
&lt;li&gt;Then we check if all of the activities have closed. What will happen once the activities are scheduled for cancellation is that each one will eventually cancel and then close. This will cause the event to be raised and we step through the above pieces again. Once every activity is done, we finally close out the activity itself.&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Using it&lt;/h3&gt;
&lt;p&gt;I placed the activity in a workflow, configured it with five approvers and set it for two to be required to move on. I also placed a code activity outputting "Ahhh, I'm done". I also put a Throw activity in there to raise an exception and cause compensation to occur to illustrate that only the two that completed are compensated for.
&lt;p&gt;&lt;img height="306" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/ImplementingtheNofMPatterninWF_F7F8/clip_image004%5B1%5D%5B1%5D_2.png" width="200"&gt;&lt;img height="353" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/ImplementingtheNofMPatterninWF_F7F8/clip_image005_1.png" width="672"&gt;
&lt;p&gt;So, what did we do?
&lt;ul&gt;
&lt;li&gt;Create a custom composite activity with the execution logic to implement an n-of-m pattern
&lt;li&gt;Saw how we can use IEventActivityListener in order to handle events raised by our child activities
&lt;li&gt;Saw how to handle potentially long running cancellation logic, and how to cancel running activities in general.
&lt;li&gt;Saw how compensation only occurs for activities that have completed successfully&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;Extensions to this idea:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;More sophisticated rules surrounding the approval (if a VP or two GM's say no, we must stop)
&lt;li&gt;Non binary choices (interesting for scoring scenarios, if the average score gets above 95%, regardless of how many approvers remaining, we move on)
&lt;li&gt;Create a designer to visualize this, especially when displayed in the workflow monitor to track it
&lt;li&gt;Validation (don't let me specify 7 approvals required, and only 3 people)&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3556624" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mwinkle/archive/tags/wf/default.aspx">wf</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/activities/default.aspx">activities</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/patterns/default.aspx">patterns</category></item><item><title>Different Execution Patterns with WF (or, Going beyond Sequential and State Machine)</title><link>http://blogs.msdn.com/mwinkle/archive/2007/05/24/different-execution-patterns-with-wf-or-going-beyond-sequential-and-state-machine.aspx</link><pubDate>Fri, 25 May 2007 00:34:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2850983</guid><dc:creator>mwinkle</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/2850983.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=2850983</wfw:commentRss><description>&lt;h2&gt;How do I do this? &lt;/h2&gt; &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="241" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_thumb.png" width="368" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;A lot of times people get stuck with the impression that there are only two workflow models available: sequential and state machine. True, out of the box these are the two that are built in, but only because there are is a set of common problems that map nicely into their execution semantics. As a result of these two being "in the box," I often see people doing a lot of very unnatural things in order to fit their problem into a certain model.  &lt;p&gt;The drawing above illustrates the flow of one such pattern. In this case, the customer wanted parallel execution with two branches ((1,3) and (2,5)). But, they had an additional factor that played in here, 4 could execute, but it could only execute when both 1 and 2 had completed. 4 didn't need to wait for 3 and 5 to finish, 3 and 5 could take a long period of time, so 4 could at least start once 1 and 2 were completed. Before we dive into a more simple solution, let's look at some of the ways they tried to solve the problem, in an attempt to use "what's in the box."  &lt;h3&gt;The "While-polling" approach &lt;/h3&gt; &lt;p align="center"&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_1.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="287" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_thumb_1.png" width="359" align="left" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&amp;nbsp;  &lt;p&gt;The basic idea behind this approach is that we will use a parallel activity, and in the third branch we will place a while loop that loops on the condition of "if activity x is done" with a brief delay activity in there so that we are not busy polling. What's the downside to this approach:  &lt;ul&gt; &lt;li&gt;The model is unnatural, and gets more awkward given the complexity of the process (what do we do if activity 7 has a dependency on 4 and 5)  &lt;li&gt;The polling and waiting is just not an efficient way to solve the problem  &lt;li&gt;This Is a lot to ask a developer to do in order to translate the representation she has in her head (first diagram, with the model we are forcing into).&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;The SynchScope approach &lt;/h3&gt; &lt;p&gt;WF V1 does have the idea of synchronizing some execution by using the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.componentmodel.synchronizationscopeactivity.aspx"&gt;SynchronizationScope&lt;/a&gt; activity. The basic idea behind the SynchronizationScope is that one can specify a set of handles that the activity must be able to acquire before allowing it's contained activities to execute. This let's us serialize access and execution. We could use this to mimic some of the behavior that the polling is doing above. We will use sigma(x, y, z) to indicate the synchronization scope and it's handles (just because I don't get to use nearly as many Greek letters as I used to).  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_2.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="267" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_thumb_2.png" width="514" align="right" border="0"&gt;&lt;/a&gt;  &lt;p&gt;This should work, provided the synchronization scopes can obtain the handles in the "correct" or "intended" order. Again, the downside here is that this gets to be pretty complex, how do we model 4 having a dependency on 3 and 2? Well, our first synchronization scope now needs to extend to cover the whole left branch, and then it should work. For the simple case like the process map I drew at the beginning, this will probably work, but as the dependency map gets deeper, we are going to run into more problems trying to make this work.  &lt;h2&gt;Creating a New Execution Pattern &lt;/h2&gt; &lt;p&gt;WF is intended to be a general purpose process engine, not just a sequential or state machine process engine. We can write our own process execution patterns by writing our own custom composite activity. Let's first describe what this needs to do:  &lt;ul&gt; &lt;li&gt; &lt;p&gt;Allow activities to be scheduled based on all of their dependent activities having executed.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;We will start by writing a custom activity that has a property for expressing dependencies. A more robust implementation would use &lt;a href="http://msdn2.microsoft.com/en-us/library/system.workflow.componentmodel.dependencyproperty.registerattached.aspx"&gt;attached properties&lt;/a&gt; to push those down to any contained activity&lt;/li&gt;&lt;/ul&gt; &lt;li&gt;Analyze the list of dependencies to determine which activities we can start executing (perhaps in parallel)  &lt;li&gt;When any activity completes, check where we are at and if any dependencies are now satisfied. If they are, schedule those for execution.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;So, how do we go about doing this?&lt;/p&gt; &lt;h3&gt;Create a simple activity with a "Preconditions" property&lt;/h3&gt; &lt;p&gt;In the future, this will be any activity using an attached property, but I want to start small and focus on the execution logic. This one is a simple Activity with a "Preconditions" array of strings where the strings will be the names of the activities which must execute first:&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SampleWithPreconProperty: Activity
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; SampleWithPreconProperty()
    {
        InitializeComponent();
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] preconditions = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[0];

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] Preconditions
    {
        get { &lt;span class="kwrd"&gt;return&lt;/span&gt; preconditions; }
        set { preconditions = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
    }
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;h3&gt;Create the PreConditionExecutor Activity&lt;/h3&gt;
&lt;p&gt;Let's first look at the declaration and the members:&lt;/p&gt;&lt;pre class="csharpcode"&gt;[Designer(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(SequentialActivityDesigner),&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(IDesigner))]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PreConditionExecutor : CompositeActivity
{
    &lt;span class="rem"&gt;// this is a dictionary of the executed activities to be indexed via&lt;/span&gt;
    &lt;span class="rem"&gt;// activity name&lt;/span&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; executedActivities = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;();

    &lt;span class="rem"&gt;// this is a dictionary of activities marked to execute (so we don't &lt;/span&gt;
    &lt;span class="rem"&gt;// try to schedule the same activity twice)&lt;/span&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; markedToExecuteActivities = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt;();

    &lt;span class="rem"&gt;// dependency maps&lt;/span&gt;
    &lt;span class="rem"&gt;// currently dictionary&amp;lt;string, list&amp;lt;string&amp;gt;&amp;gt; that can be read as &lt;/span&gt;
    &lt;span class="rem"&gt;// activity x has dependencies in list a, b, c&lt;/span&gt;
    &lt;span class="rem"&gt;// A more sophisticated implementation will use a graph object to track&lt;/span&gt;
    &lt;span class="rem"&gt;// execution paths and be able to check for completeness, loops, all&lt;/span&gt;
    &lt;span class="rem"&gt;// that fun graph theory stuff I haven't thought about in a while&lt;/span&gt;
    &lt;span class="kwrd"&gt;private&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; dependencyMap = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;();
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;We have three dictionaries, one to track which have completed, one for which ones are scheduled for execution, and one to map the dependencies. As noted in the comments, a directed graph would be a better representation of this so that we could do some more sophisticated analysis on it.&lt;/p&gt;
&lt;p&gt;Now, let's look at the Execute method, the one that does all the work.&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (0 == Activities.Count)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; ActivityExecutionStatus.Closed;
    }
    &lt;span class="rem"&gt;// loop through the activities and mark those that have no preconditions&lt;/span&gt;
    &lt;span class="rem"&gt;// as ok to execute and put those in the queue&lt;/span&gt;
    &lt;span class="rem"&gt;// also generate the graph which will determine future activity execution.&lt;/span&gt;
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Activity a &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities)
    {
        &lt;span class="rem"&gt;// start with our basic activity&lt;/span&gt;
        SampleWithPreconProperty preconActivity = a &lt;span class="kwrd"&gt;as&lt;/span&gt; SampleWithPreconProperty;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; == preconActivity)
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Exception(&lt;span class="str"&gt;"Not right now, we're not that fancy"&lt;/span&gt;);
        }
        &lt;span class="rem"&gt;// construct the execution dictionary&lt;/span&gt;
        executedActivities.Add(a.Name, &lt;span class="kwrd"&gt;false&lt;/span&gt;);
        markedToExecuteActivities.Add(a.Name, &lt;span class="kwrd"&gt;false&lt;/span&gt;);
        List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; actDependencies = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != preconActivity.Preconditions)
        {
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; s &lt;span class="kwrd"&gt;in&lt;/span&gt; preconActivity.Preconditions)
            {
                actDependencies.Add(s);
            }
        }
        dependencyMap.Add(a.Name, actDependencies);
    }
    &lt;span class="rem"&gt;// now we have constructed our execution map and our dependency map&lt;/span&gt;
    &lt;span class="rem"&gt;// let's do something with those, like find those activities with&lt;/span&gt;
    &lt;span class="rem"&gt;// no dependencies and schedule those for execution.&lt;/span&gt;
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Activity a &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (0 == dependencyMap[a.Name].Count)
        {
            Activity executeThis = &lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities[a.Name];
            executeThis.Closed += currentlyExecutingActivity_Closed;
            markedToExecuteActivities[a.Name] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            executionContext.ExecuteActivity(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities[a.Name]);
            Console.WriteLine(&lt;span class="str"&gt;"Scheduled: {0}"&lt;/span&gt;, a.Name);
        }
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; ActivityExecutionStatus.Executing;
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Basically, we first construct the execution tracking dictionaries, initializing those to false. We then create the dictionary of dependencies. We then loop through the activities and see if there are any that have no dependencies (there has to be one, this would be a good point to raise an exception if there isn't. We record in the dictionary that this one has been marked to execute and then we schedule it for execution (after hooking the Closed event so that we can do some more work later). So what happens when we close?&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; currentlyExecutingActivity_Closed(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ActivityExecutionStatusChangedEventArgs e)
{
    e.Activity.Closed -= &lt;span class="kwrd"&gt;this&lt;/span&gt;.currentlyExecutingActivity_Closed;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.ExecutionStatus == ActivityExecutionStatus.Canceling)
    {
        ActivityExecutionContext context = sender &lt;span class="kwrd"&gt;as&lt;/span&gt; ActivityExecutionContext;
        context.CloseActivity();
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.ExecutionStatus == ActivityExecutionStatus.Executing)
    {
        &lt;span class="rem"&gt;// set the Executed Dictionary&lt;/span&gt;
        executedActivities[e.Activity.Name] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (executedActivities.ContainsValue(&lt;span class="kwrd"&gt;false&lt;/span&gt;) &lt;span class="rem"&gt;/* keep going */&lt;/span&gt;)
        {
            &lt;span class="rem"&gt;// find all the activities that contain the precondition &lt;/span&gt;
            &lt;span class="rem"&gt;// and remove them, and then cycle through any that have 0 &lt;/span&gt;
            &lt;span class="rem"&gt;// preconditions (and have not already executed or are marked&lt;/span&gt;
            &lt;span class="rem"&gt;// to execute&lt;/span&gt;
            &lt;span class="rem"&gt;// who contains this precondition? &lt;/span&gt;
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Activity a &lt;span class="kwrd"&gt;in&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.Activities)
            {
                &lt;span class="rem"&gt;// filter out those activities executed or executing&lt;/span&gt;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!(executedActivities[a.Name] || markedToExecuteActivities[a.Name]))
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (dependencyMap[a.Name].Contains(e.Activity.Name))
                    {
                        &lt;span class="rem"&gt;// we found it, remove it&lt;/span&gt;
                        dependencyMap[a.Name].Remove(e.Activity.Name);
                        &lt;span class="rem"&gt;// if we now have no dependencies, let's schedule it&lt;/span&gt;
                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (0 == dependencyMap[a.Name].Count)
                        {
                            a.Closed += currentlyExecutingActivity_Closed;
                            ActivityExecutionContext context = sender &lt;span class="kwrd"&gt;as&lt;/span&gt; ActivityExecutionContext;
                            markedToExecuteActivities[a.Name] = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
                            context.ExecuteActivity(a);
                            Console.WriteLine(&lt;span class="str"&gt;"Scheduled: {0}"&lt;/span&gt;, a.Name);
                        }
                    }
                }
            }
        }
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="rem"&gt;//close activity&lt;/span&gt;
        {
            ActivityExecutionContext context = sender &lt;span class="kwrd"&gt;as&lt;/span&gt; ActivityExecutionContext;
            context.CloseActivity();
        }
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There are a few lines of code here, but it's pretty simple what's going on. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We remove the event handler 
&lt;li&gt;If we're still executing, mark the list of activities appropriately 
&lt;li&gt;Loop through and see if any of them have dependencies on the activity which just now completed being done 
&lt;li&gt;If they do, remove that entry from the dependency list and check if we can run it (if the count == 0). If we can, schedule it, otherwise keep looping. 
&lt;li&gt;If all the activities have completed (there is no false in the Executed list) then we will close out this activity.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;To actually use this activity, we place it in the workflow, place a number of the child activity types within it (again, with the attached property, you could put nearly any activity in there) and specify the activities that it depends on. Since I haven't put a designer on it, I just use the SequenceDesigner. Here's what it looks like (this is like the graph I drew above but kicks off with the "one" activity executing first:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_3.png" atomicselection="true"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="451" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/DifferentExecutionPatternswithWForGoingb_CCEE/image_thumb_3.png" width="722" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;Where can we go from here &lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Validation, remember all that fun graph theory stuff checking for cycles and completeness and no gaps. Yeah, we should probably wire some of that stuff up here to make sure we can actually execute this thing 
&lt;li&gt;Analysis of this might be interesting, especially as the process gets more complex (identifying complex dependencies, places for optimization, capacity stuff) 
&lt;li&gt;A designer to actually do all of this automatically. Right now, it is left as an exercise to the developer to express the dependencies by way of the properties. It would be nice to have a designer that would figure that out for you, and also validate so you don't try to do the impossible.
&lt;li&gt;Make this much more dynamic and pull in the preconditions and generate the context for the activities on the fly.&amp;nbsp; This would be cool if you had a standard "approval" activity that you wanted to have a more configurable execution pattern.&amp;nbsp; You could build the graph through the designer and then use that to drive the execution&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;I'm going to hold off on posting the code, as I've got a few of these and I'd like to come up with some way to put them out there that would make it easy to get to them and use them. You should be able to pretty easily construct your own activity based on the code presented here.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2850983" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mwinkle/archive/tags/wf/default.aspx">wf</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/activities/default.aspx">activities</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/patterns/default.aspx">patterns</category></item></channel></rss>