<?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 : presentations</title><link>http://blogs.msdn.com/mwinkle/archive/tags/presentations/default.aspx</link><description>Tags: presentations</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>Advanced Workflow Services Talk (Demo 3 of 4)</title><link>http://blogs.msdn.com/mwinkle/archive/2008/08/07/advanced-workflow-services-talk-demo-3-of-4.aspx</link><pubDate>Fri, 08 Aug 2008 00:17:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8841711</guid><dc:creator>mwinkle</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/8841711.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=8841711</wfw:commentRss><description>&lt;p&gt;So, we've seen in part 1 how to manage context, we saw in part 2 how we can take that basic knowledge to do duplex messaging.&amp;#160; Once we start doing duplex work, there are some interesting patterns, and the first one is one that we like to call &amp;quot;long running work&amp;quot;.&amp;#160; Why are we interested in this?&amp;#160; Well, as you probably know, the execution of a workflow is single threaded (this is a feature, not a bug).&amp;#160; We also don't have a mechanism to force the workflow to be &amp;quot;pinned&amp;quot; in memory.&amp;#160; What this means is that things like the asynchronous programming model&amp;#160; (APM), can't be used, since there isn't a guarantee that there will be something to call back when we are done.&amp;#160; What this means is that the send activity can not take advantage of the APM to be more thread friendly.&lt;/p&gt;  &lt;p&gt;We may want to do things in parallel, like this&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo3of4_D4A0/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="309" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo3of4_D4A0/image_thumb.png" width="616" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;If each of these branches takes 3 seconds, the whole of this workflow will complete in about 9 seconds.&amp;#160; The general expectation is that in parallel, this would happen at the length of the longest branch + some minor delta for overhead.&amp;#160; The trouble is, APM programming is tricky, especially relative to the layout above.&lt;/p&gt;  &lt;p&gt;In order to model APM style service calls, but allowing for the service operations to be extremely long running, where extremely is defined as &amp;quot;long enough to where I would want to be able to persist.&amp;quot;&amp;#160; The approach then is to model this as disjoint send and receive activities.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo3of4_D4A0/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="386" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo3of4_D4A0/image_thumb_1.png" width="632" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;One intermediate step is to simply use one way messaging, but the problem there is that in a lot of cases, I'm looking for some information being sent back to me.&amp;#160; &lt;/p&gt;  &lt;p&gt;I'll hold off on the code for the above, the fact we are listening in parallel for the same operation requires us to be a little more clever. &lt;/p&gt;  &lt;p&gt;Let's look first at our contract, and then our service implementation:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Long_Running_Work&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    [ServiceContract]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; ILongRunningWork&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        [OperationContract]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; TakeAWhile(&lt;span class="kwrd"&gt;int&lt;/span&gt; i);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; OneWayTakeAWhile( &lt;span class="kwrd"&gt;int&lt;/span&gt; i);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeAWhileAndTellMeLater(IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;,&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; contextToken, &lt;span class="kwrd"&gt;int&lt;/span&gt; i);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    [ServiceContract]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IReverseContract&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeAWhileAndTellMeLaterDone(&lt;span class="kwrd"&gt;string&lt;/span&gt; s);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;   &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&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;And now for the implementation of these;&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; Long_Running_Work&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Service1 : ILongRunningWork&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; Service1()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;           &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;span class="preproc"&gt;#region&lt;/span&gt; ILongRunningWork Members&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; TakeAWhile(&lt;span class="kwrd"&gt;int&lt;/span&gt; i)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Starting TakeAWhile&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            System.Threading.Thread.Sleep(&lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(0, 0, 3));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; i.ToString();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OneWayTakeAWhile( &lt;span class="kwrd"&gt;int&lt;/span&gt; i)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Starting One Way TakeAWhile&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            System.Threading.Thread.Sleep(&lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(0, 0, 3));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Ending One Way TakeAWhile&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeAWhileAndTellMeLater(IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; context, &lt;span class="kwrd"&gt;int&lt;/span&gt; i)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Received the context Token&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            System.Threading.Thread.Sleep(&lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(0, 0, 3));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Need to Message Back Now {0}&amp;quot;&lt;/span&gt;, i.ToString());&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            &lt;span class="rem"&gt;// could investigate a more useful pooling of these if we &lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;            &lt;span class="rem"&gt;// really wanted to worry about perf&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;            IReverseContractClient ircc = &lt;span class="kwrd"&gt;new&lt;/span&gt; IReverseContractClient(&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(&lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10003/ReverseContract&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;                );&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;            IContextManager icm = ircc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;            icm.SetContext(context);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;            ircc.TakeAWhileAndTellMeLaterDone(i.ToString());&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;        &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;    } &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;   &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; IReverseContractClient : ClientBase&amp;lt;IReverseContract&amp;gt;, IReverseContract&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;   {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; IReverseContractClient() : &lt;span class="kwrd"&gt;base&lt;/span&gt;(){}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; IReverseContractClient(System.ServiceModel.Channels.Binding binding, EndpointAddress address) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(binding, address) { }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  57:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  58:  &lt;/span&gt;&lt;span class="preproc"&gt;#region&lt;/span&gt; IReverseContract Members&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  59:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  60:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  61:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  62:  &lt;/span&gt;       &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TakeAWhileAndTellMeLaterDone(&lt;span class="kwrd"&gt;string&lt;/span&gt; s)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  63:  &lt;/span&gt;       {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  64:  &lt;/span&gt;           &lt;span class="kwrd"&gt;base&lt;/span&gt;.Channel.TakeAWhileAndTellMeLaterDone(s);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  65:  &lt;/span&gt;       }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  66:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  67:  &lt;/span&gt;       &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  68:  &lt;/span&gt;   }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  69:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  70:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&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 sit around and wait.&amp;#160; You'll also note in the TakeAWhileAndTellMeLater, we take in a context token (similar to our previous approach), and we will use that to new up a client at the end and call back in after setting the context.&amp;#160; Look at lines 39-44 above.&amp;#160; The nice thing about this is that my above workflow client can actually go idle, persist, and react to a message being delivered later on.&lt;/p&gt;

&lt;p&gt;One thing to note is that one should not place a delay between any of the Send and Receives.&amp;#160; This could cause the workflow to go idle, which may allow you to miss messages.&amp;#160; This is generally considered, a bad thing.&amp;#160; The reason this occurs is that the WorkflowOperationInvoker will use EnqueueOnIdle which means that when teh workflow goes idle, the message will be enqueued.&amp;#160; If the queue hasn't been created by the Receive activity, the message will not get delivered.&lt;/p&gt;

&lt;p&gt;For the final workflow above (the TakeAWhileAndTellMeLater workflow), I will need to spin this up in a WorkflowServiceHost (a la the Duplex Sample in part 2).&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; (WorkflowServiceHost wsh = &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkflowServiceHost(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(CallLongRunningComponents.WorkflowWithmessaging)))
{
    wsh.AddServiceEndpoint(
            &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Long_Running_Work.IReverseContract),
            &lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),
           &lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10003/ReverseContract&amp;quot;&lt;/span&gt;
            );
    &lt;span class="rem"&gt;// don't forget to open up the wsh&lt;/span&gt;
    WorkflowRuntime wr = wsh.Description.Behaviors.Find&amp;lt;WorkflowRuntimeBehavior&amp;gt;().WorkflowRuntime;

    wsh.Open();


    WorkflowInstance wi = wr.CreateWorkflow(
        &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(CallLongRunningComponents.WorkflowWithmessaging));
    wr.WorkflowCompleted += ((o, e) =&amp;gt; waitHandle.Set());
    wr.WorkflowIdled += ((o, e) =&amp;gt; Console.WriteLine(&lt;span class="str"&gt;&amp;quot;We're idled&amp;quot;&lt;/span&gt;));
        

    wi.Start();




    waitHandle.WaitOne();

}&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;Why do I think this is cool? &lt;/p&gt;

&lt;p&gt;Two reasons:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If I assume that I can modify the called service to callback to me (or put such a wrapper at a runtime service level), this is easier to model than the APM (that code included at the end of this post) &lt;/li&gt;

  &lt;li&gt;This gives me a natural way to start exposing more advanced control over a service call.&amp;#160; Rather than just a send and receive, I can use a send and a listen, and in the listen have a receive, a cancel message receive, and a delay in order to expose more fine grained control points for my workflow, and model the way the process should work very explicitly and declaratively. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo3of4_D4A0/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="503" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo3of4_D4A0/image_thumb_2.png" width="449" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Code for APM approach:&lt;/h4&gt;

&lt;p&gt;call some services and wait:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press &amp;lt;enter&amp;gt; to execute APM approach&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;Console.ReadLine();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;waitHandle = &lt;span class="kwrd"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span class="kwrd"&gt;false&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;Stopwatch sw = &lt;span class="kwrd"&gt;new&lt;/span&gt; Stopwatch();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;sw.Start();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;lrwc = &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkflowHost.ServiceReference1.LongRunningWorkClient();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;lrwc.BeginTakeAWhile(1, HandleClientReturn, &lt;span class="str"&gt;&amp;quot;one&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;lrwc.BeginTakeAWhile(2, HandleClientReturn, &lt;span class="str"&gt;&amp;quot;two&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;lrwc.BeginTakeAWhile(3, HandleClientReturn, &lt;span class="str"&gt;&amp;quot;three&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;lrwc.BeginTakeAWhile(4, HandleClientReturn, &lt;span class="str"&gt;&amp;quot;four&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; (!areDone)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    System.Threading.Thread.Sleep(25);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;APM approach compelted in {0} milliseconds&amp;quot;&lt;/span&gt;, sw.ElapsedMilliseconds);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;Console.WriteLine(&lt;span class="str"&gt;&amp;quot;All Done, press &amp;lt;enter&amp;gt; to exit&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;Console.ReadLine();&lt;/pre&gt;
&lt;/div&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;Ignore the busy wait on line 11, I should use a waithandle here but was having trouble getting it to work correctly (this is hard code).&lt;/p&gt;

&lt;p&gt;The callback and respective state:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; ServiceReference1.LongRunningWorkClient lrwc;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; Int32 countOfFinished = 0;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; HandleClientReturn(IAsyncResult result)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; s = (&lt;span class="kwrd"&gt;string&lt;/span&gt;)result.AsyncState;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; resultString = lrwc.EndTakeAWhile(result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;received {0}&amp;quot;&lt;/span&gt;, resultString);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Interlocked.Increment(&lt;span class="kwrd"&gt;ref&lt;/span&gt; countOfFinished) == 4)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        areDone = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&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;p&gt;I have had some people say that line 9 should use &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.interlocked.compareexchange.aspx"&gt;Interlocked.CompareExchange&lt;/a&gt; in order to do this correctly, but the point is that this is tricky code, that modeling in WF is pretty nice.&amp;#160; [ignoring for the moment the work required to realize the assumption that we can make the service message back.]&amp;#160; &lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8841711" 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/presentations/default.aspx">presentations</category></item><item><title>Advanced Workflow Services Talk (Demo 2 of 4)</title><link>http://blogs.msdn.com/mwinkle/archive/2008/08/06/advanced-workflow-services-talk-demo-2-of-4.aspx</link><pubDate>Wed, 06 Aug 2008 21:30:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8838441</guid><dc:creator>mwinkle</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/8838441.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=8838441</wfw:commentRss><description>&lt;p&gt;A continuation of my series of demos from my advanced workflow services talk.&amp;#160; Here we focus on duplex message exchange patterns.&lt;/p&gt;  &lt;p&gt;Duplex messaging is something that we model at the application level (as opposed to the infrastructure level) because we want to model that message exchange at the level of the application.&amp;#160; Here's some scenarios where I could use duplex messaging:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;[concrete] I submit an order, and you tell me when it ships &lt;/li&gt;    &lt;li&gt;[abstract] I ask you do to do some long running work, let me know when it is done &lt;/li&gt;    &lt;li&gt;[abstract] I ask you to start doing something, you update me on the status &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;One may ask the question, &amp;quot;But, what about the wsHttpDualBinding, or WCF duplex bindings.&amp;quot;&amp;#160; That's a valid question, but it's important to point out that those bindings are really used to describe the behavior of a given proxy instance (and associated service artifacts).&amp;#160; When my proxy dies, or the underlying connection goes away, I lose the ability for the service to call back to me.&amp;#160; Additionally, this binds me to listen in the same way that I sent out the initial message.&amp;#160; &lt;/p&gt;  &lt;p&gt;By modeling this at the application layer, we do lose some of the &amp;quot;automagicity&amp;quot; of the WCF duplex behavior, but I get more flexibility, and I get the ability to sustain potentially repeated recycling of the services and clients.&amp;#160; Also, you could imagine a service that I call that turns around and calls a third party service.&amp;#160; That third party service could call back directly to the client that made the initial call.&amp;#160; Note, once we start doing duplex communication (and we'll encounter this in part 4, conversations), is that the definition of &amp;quot;client&amp;quot; and &amp;quot;service&amp;quot; become a bit muddier.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;So, to the code:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Ingredients:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;My service workflow, I listen for three different messages (start, add item, complete ), and then I will send the message back to the client: &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo2of4_C68C/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="855" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo2of4_C68C/image_thumb.png" width="450" border="0" /&gt;&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;You'll note that there is a loop so that we can keep adding items until we eventually get the complete order message and we then exit the loop. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;A &amp;quot;client&amp;quot; workflow, which will call this service: &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo2of4_C68C/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="667" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo2of4_C68C/image_thumb_1.png" width="234" border="0" /&gt;&lt;/a&gt;       &lt;ul&gt;       &lt;li&gt;You'll note, some of &lt;strong&gt;&lt;em&gt;the magic happens here&lt;/em&gt;&lt;/strong&gt;.&amp;#160; After I start, add and complete the order, you'll see that instead of sending messages, I'll now flip around and wait on the receive in order to receive the shipping cost from the service. &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Details&lt;/h4&gt;  &lt;p&gt;The first thing that we need to do in order to enable this duplex messaging to occur is that the &amp;quot;client&amp;quot; workflow has to explicitly provide its context token to the service so that the service can address the appropriate instance of the client workflow.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Note, in the real world, you'll probably need to supply more than just the context token, you will need some address and binding information.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Let's look at the contract of the service:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;[ServiceContract(Namespace =&lt;span class="str"&gt;&amp;quot;http://microsoft.com/dpe/samples/duplex&amp;quot;&lt;/span&gt;)]
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt;  IOrderProcessing
{
    [OperationContract()]
    &lt;span class="kwrd"&gt;void&lt;/span&gt; SubmitOrder(&lt;span class="kwrd"&gt;string&lt;/span&gt; customerName, &lt;font color="#ff0000"&gt;IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; context&lt;/font&gt;);

    [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt; )]
    &lt;span class="kwrd"&gt;void&lt;/span&gt; AddItem(OrderItem orderItem);

    [OperationContract(IsOneWay = &lt;span class="kwrd"&gt;true&lt;/span&gt; )]
    &lt;span class="kwrd"&gt;void&lt;/span&gt; CompleteOrder();
}&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;You'll note that on the SubmitOrder method, I pass in a context token.&amp;#160; This is my callback correlation identifier, this is how I will figure out what instance on the client side I want to talk to.&amp;#160; Now, I need to do some work to get the context token in order to send, so let's look at how we do this:&lt;/p&gt;

&lt;p&gt;On the client side, on the first Send activity, let's hook the BeforeSend event.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo2of4_C68C/image_6.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="292" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo2of4_C68C/image_thumb_2.png" width="278" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Let's look at the implementation of GrabToken:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; GrabToken(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, SendActivityEventArgs e)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    ContextToSend = receiveActivity1.Context;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Received token to send along&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DependencyProperty ContextToSendProperty = DependencyProperty.Register(&lt;span class="str"&gt;&amp;quot;ContextToSend&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(System.Collections.Generic.IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, System.String&amp;gt;), &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(OrderSubmitter.Workflow1));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;[BrowsableAttribute(&lt;span class="kwrd"&gt;true&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;[CategoryAttribute(&lt;span class="str"&gt;&amp;quot;Parameters&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; System.Collections.Generic.IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, String&amp;gt; ContextToSend&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    get&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ((System.Collections.Generic.IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;)(&lt;span class="kwrd"&gt;base&lt;/span&gt;.GetValue(OrderSubmitter.Workflow1.ContextToSendProperty)));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    set&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;span class="kwrd"&gt;base&lt;/span&gt;.SetValue(OrderSubmitter.Workflow1.ContextToSendProperty, &lt;span class="kwrd"&gt;value&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&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;First, note that on lines 7-22 we declare a dependency property call ContextToSend.&amp;#160; Think of this simply as a bindable storage space.&amp;#160; On line 3, we go and assign to that the value of receiveActivity1.Context.&amp;#160; &amp;quot;But Matt, couldn't I just build a context token off the workflow ID?&amp;quot;&amp;#160; You could, but you're only going to be correct in the &amp;quot;simple scenario.&amp;quot;&amp;#160;&amp;#160; You can see we then take that ContextToSend, and pass that into the context parameter for the service operation. &lt;strong&gt;Always walk up and ask a Receive activity for its context token, don't try to build one on your own.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, on the service side, we need to extract that, and we need to apply the value to the send activity in the service workflow that needs to call back.&amp;#160; We basically can do the reverse:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; codeActivity1_ExecuteCode(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    &lt;span class="rem"&gt;//set callback context&lt;/span&gt;
    sendActivity1.Context = callbackContext;
}&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;This is inside a code activity in the first receive activity.&amp;#160; callbackContext is a dependency property that is bound to the inbound context on the Receive activity.&amp;#160; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The final trick is that both workflows have to be hosted inside a WorkflowServiceHost.&amp;#160; This makes sense for the &amp;quot;service&amp;quot; workflow, since it will be message activated.&amp;#160; On the client side, we have to do a little bit of work in order to get to the workflow runtime to spin up a workflow instance.&amp;#160; In the early betas, we had an easy way to get to the runtime, WorkflowServiceHost.WorkflowRuntime.&amp;#160; In order to conform more with the extensibility of WCF, this has been moved to the extensions of the service host.&amp;#160; We get there by:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (WorkflowServiceHost wsh = &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkflowServiceHost(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Workflow1)))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press &amp;lt;ENTER&amp;gt; to start the workflow&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        Console.ReadLine();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        wsh.Open();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        WorkflowRuntime wr = wsh.Description.Behaviors.Find&amp;lt;WorkflowRuntimeBehavior&amp;gt;().WorkflowRuntime;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        WorkflowInstance wi = wr.CreateWorkflow(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Workflow1));&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        AutoResetEvent waitHandle = &lt;span class="kwrd"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span class="kwrd"&gt;false&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        wr.WorkflowCompleted += &lt;span class="kwrd"&gt;delegate&lt;/span&gt; { waitHandle.Set(); };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        wr.WorkflowTerminated += &lt;span class="kwrd"&gt;delegate&lt;/span&gt;(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WorkflowTerminatedEventArgs e) { Console.WriteLine(&lt;span class="str"&gt;&amp;quot;error {0}&amp;quot;&lt;/span&gt;, e); waitHandle.Set(); };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        wi.Start();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        waitHandle.WaitOne();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Workflow Completed&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        Console.ReadLine();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&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;On line 3, you'll see we new up a WorkflowServiceHost based on the service type (it will do this to find and open the respective endpoints).&amp;#160; On line 8, we reach in and grab the WorkflowRuntimeBehavior and get the WorkflowRuntime, and we use that to create an instance of the workflow.&amp;#160; &lt;/p&gt;

&lt;p&gt;So, here's what we have done:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Figure out how to grab the context token from a Receive activity &lt;/li&gt;

  &lt;li&gt;Modify the contract to explicitly send the &amp;quot;callback info&amp;quot; to the service &lt;/li&gt;

  &lt;li&gt;On the service side, figure out how to grab that and apply it to a Send activity &lt;/li&gt;

  &lt;li&gt;Finally, on the client side, how to manually kick off workflows, rather than waiting for them to be message activated (the usual path we have is the infrastructure creating the workflow instance).&amp;#160; &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8838441" 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/presentations/default.aspx">presentations</category></item><item><title>Advanced Workflow Services Talk (Demo 1 of 4)</title><link>http://blogs.msdn.com/mwinkle/archive/2008/08/05/advanced-workflow-services-talk-demo-1-of-4.aspx</link><pubDate>Tue, 05 Aug 2008 20:44:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8834527</guid><dc:creator>mwinkle</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/8834527.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=8834527</wfw:commentRss><description>&lt;p&gt;So, last week I wrapped up a conversation at TechReady, our internal conference, where I was talking about the integration between WF and WCF in .NET 3.5.&amp;#160; This talk was somewhat bittersweet, it's the last conference where I'm scheduled to talk about WF 3.0/3.5, I'll start talking about WF 4.0 at PDC this fall.&amp;#160; &lt;/p&gt;  &lt;p&gt;There are a series of 4 demos that we'll talk about in this series:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Basic Context Management &lt;/li&gt;    &lt;li&gt;Simple Duplex &lt;/li&gt;    &lt;li&gt;Long Running Work Pattern &lt;/li&gt;    &lt;li&gt;Conversations Pattern &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I've gotten a lot of requests to post the code samples, so I want to do that here:&lt;/p&gt;  &lt;h1&gt;Sample 1, Basic Management of Context&lt;/h1&gt;  &lt;p&gt;The goal of this sample is to show the way that the context channel works, and how to interact with it from imperative code.&lt;/p&gt;  &lt;h3&gt;Ingredients: &lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;One basic workflow service that simply has two Receive activities bound to the same operation inside of a sequence. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo1ofn_AAA5/image_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="380" alt="image" src="http://blogs.msdn.com/blogfiles/mwinkle/WindowsLiveWriter/AdvancedWorkflowServicesTalkDemo1ofn_AAA5/image_thumb.png" width="279" border="0" /&gt;&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Inside each Receive, I have placed a Code Activity that simply outputs a little bit of info (the vars declared on lines 1 and 2 are used by the Receive activities: &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;ul&gt;   &lt;div class="csharpcode"&gt;     &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; String returnValue = &lt;span class="kwrd"&gt;default&lt;/span&gt;(System.String);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; String inputMessage = &lt;span class="kwrd"&gt;default&lt;/span&gt;(System.String);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; codeActivity1_ExecuteCode(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    returnValue = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;first activity {0}&amp;quot;&lt;/span&gt;, inputMessage);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    Output(inputMessage + &lt;span class="str"&gt;&amp;quot; Activity 1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;}&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Output(&lt;span class="kwrd"&gt;string&lt;/span&gt; message)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Workflow {0} : Message {1}&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;this&lt;/span&gt;.WorkflowInstanceId, message);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;}&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; codeActivity2_ExecuteCode(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;{&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    returnValue = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;second activity {0}&amp;quot;&lt;/span&gt;, inputMessage);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    Output(inputMessage + &lt;span class="str"&gt;&amp;quot; Activity 2&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;}&lt;/pre&gt;
  &lt;/div&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;/ul&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;Instructions: &lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Create a client type that will call the service for us 
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; IWorkflowClient : ClientBase&amp;lt;Intro1.IWorkflow1&amp;gt;, Intro1.IWorkflow1
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IWorkflowClient() : &lt;span class="kwrd"&gt;base&lt;/span&gt;() { }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; IWorkflowClient(Binding binding, EndpointAddress address) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(binding, address) { }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Hello(&lt;span class="kwrd"&gt;string&lt;/span&gt; message)
    {
        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.Channel.Hello(message);
    }
}&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;/li&gt;

  &lt;li&gt;Create a utility function CheckAndPrintContext() 
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; CheckAndPrintContext(IContextManager icm)
{
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != icm) Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Context contains {0} elements&amp;quot;&lt;/span&gt;, icm.GetContext().Count);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != icm)
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (icm.GetContext().Count &amp;gt; 0)
        {
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; xmlName &lt;span class="kwrd"&gt;in&lt;/span&gt; icm.GetContext().Keys)
            {
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;key : {0}&amp;quot;&lt;/span&gt;, xmlName);
                Console.WriteLine(&lt;span class="str"&gt;&amp;quot;value : {0}&amp;quot;&lt;/span&gt;, icm.GetContext()[xmlName]);
            }
        }
    }
}&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
  &lt;ul&gt;
    &lt;li&gt;The thing to note here is that we need to traverse the dictionary, since there could be more than one key in here, although there won't be in this sample. &lt;/li&gt;
  &lt;/ul&gt;

  &lt;li&gt;Now, let's run the three different bits of code, we want to first show the happy path, show how to break it, and then show how to explicitly manage the context token &lt;/li&gt;

  &lt;li&gt;
    &lt;h4&gt;Scenario 1: The Happy Path&lt;/h4&gt;

    &lt;div class="csharpcode"&gt;
      &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DemoOne()&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Send a Message and reuse proxy&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="rem"&gt;// Console.ReadLine();&lt;/span&gt;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    Debugger.Break();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    IWorkflowClient iwc = &lt;span class="kwrd"&gt;new&lt;/span&gt; IWorkflowClient(&lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(&lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10001/Intro1&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    IContextManager icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != icm) Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Context contains {0} elements&amp;quot;&lt;/span&gt;, icm.GetContext().Count);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; s = iwc.Hello(&lt;span class="str"&gt;&amp;quot;message1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;the service returned the message '{0}'&amp;quot;&lt;/span&gt;, s);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    CheckAndPrintContext(icm);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    s = iwc.Hello(&lt;span class="str"&gt;&amp;quot;message2&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    CheckAndPrintContext(icm);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;the service returned the message '{0}'&amp;quot;&lt;/span&gt;, s);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Continue&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;}&lt;/pre&gt;
    &lt;/div&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;ul&gt;
      &lt;li&gt;What's going on here? 
        &lt;ul&gt;
          &lt;li&gt;Line 5, a more convenient way in demos to hit a breakpoint &lt;/li&gt;

          &lt;li&gt;Line 10: Call the service &lt;/li&gt;

          &lt;li&gt;Line 12: CheckAndPrint the Context Token.&amp;#160; In this case, this will print the Guid of the initiated workflow that is contained in the token &lt;/li&gt;

          &lt;li&gt;Line 13: Call the service a second time 
            &lt;ul&gt;
              &lt;li&gt;Look at the service window, you'll see that this message has been routed to the same instance of the workflow. &lt;/li&gt;

              &lt;li&gt;You can also see in Line 16 that the second activities return message is included. &lt;/li&gt;
            &lt;/ul&gt;
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;h4&gt;Scenario 2: The Path Grows Darker&lt;/h4&gt;

    &lt;div class="csharpcode"&gt;
      &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;// show this not working using a second client&lt;/span&gt;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DemoTwo()&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Send a Message (it will break this time)&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="rem"&gt;//Console.ReadLine();&lt;/span&gt;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    Debugger.Break();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    IWorkflowClient iwc = &lt;span class="kwrd"&gt;new&lt;/span&gt; IWorkflowClient(&lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(&lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10001/Intro1&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    IContextManager icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != icm) Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Context contains {0} elements&amp;quot;&lt;/span&gt;, icm.GetContext().Count);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; s = iwc.Hello(&lt;span class="str"&gt;&amp;quot;message1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;the service returned the message '{0}'&amp;quot;&lt;/span&gt;, s);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    CheckAndPrintContext(icm);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    iwc = &lt;span class="kwrd"&gt;new&lt;/span&gt; IWorkflowClient(&lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;       &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(&lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10001/Intro1&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    s = iwc.Hello(&lt;span class="str"&gt;&amp;quot;message2&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;the service returned the message '{0}'&amp;quot;&lt;/span&gt;, s);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    CheckAndPrintContext(icm);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Continue&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;}&lt;/pre&gt;
    &lt;/div&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;ul&gt;
      &lt;li&gt;What's going on here? (Same until line 14) 
        &lt;ul&gt;
          &lt;li&gt;Line 14: Let's create a new proxy.&amp;#160; &lt;/li&gt;

          &lt;li&gt;Line 15: Call the service using the new proxy.&amp;#160; You'll note on the server side that a second workflow instance has been created.&amp;#160; This is where we break. &lt;/li&gt;

          &lt;li&gt;Line 19: On the client side, you'll see that the second GUID being returned &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;
    &lt;h4&gt;Scenario 3: Finding the Light&lt;/h4&gt;

    &lt;div class="csharpcode"&gt;
      &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="rem"&gt;// show this working with a second client by caching the context&lt;/span&gt;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DemoThree()&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Send a Message (we'll cache the context and apply it to the new proxy)&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="rem"&gt;// Console.ReadLine();&lt;/span&gt;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    Debugger.Break();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    IWorkflowClient iwc = &lt;span class="kwrd"&gt;new&lt;/span&gt; IWorkflowClient(&lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(&lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10001/Intro1&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    IContextManager icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != icm) Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Context contains {0} elements&amp;quot;&lt;/span&gt;, icm.GetContext().Count);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; s = iwc.Hello(&lt;span class="str"&gt;&amp;quot;message1&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;the service returned the message '{0}'&amp;quot;&lt;/span&gt;, s);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    CheckAndPrintContext(icm);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; context = icm.GetContext();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    icm = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    iwc = &lt;span class="kwrd"&gt;new&lt;/span&gt; IWorkflowClient(&lt;span class="kwrd"&gt;new&lt;/span&gt; NetTcpContextBinding(),&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;       &lt;span class="kwrd"&gt;new&lt;/span&gt; EndpointAddress(&lt;span class="str"&gt;&amp;quot;net.tcp://localhost:10001/Intro1&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    icm.SetContext(context);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;    s = iwc.Hello(&lt;span class="str"&gt;&amp;quot;message2&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;the service returned the message '{0}'&amp;quot;&lt;/span&gt;, s);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;    icm = iwc.InnerChannel.GetProperty&amp;lt;IContextManager&amp;gt;();&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    CheckAndPrintContext(icm);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Press Enter to Exit&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;&amp;#160;&lt;/pre&gt;

      &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;}&lt;/pre&gt;
    &lt;/div&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;ul&gt;
      &lt;li&gt;Line 14 is where the magic happens, here' we grab the context token from the IContextManager.&amp;#160; &lt;/li&gt;

      &lt;li&gt;Line 19 is where the magic completes, we apply this token to the new proxy.&amp;#160; Note, this proxy could be running on different machine somewhere, but one I get the context token, I can use it to communicate with the same workflow instance that the first call did. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, what have we shown:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Manipulating context in workflow and imperative code 
    &lt;ul&gt;
      &lt;li&gt;How to extract the context token &lt;/li&gt;

      &lt;li&gt;How to explicitly set the context token &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;The caching behavior of the context channel (as seen in Scenario 1) &lt;/li&gt;

  &lt;li&gt;The behavior of the context channel to return the context token only on the activating message &lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8834527" 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/presentations/default.aspx">presentations</category></item><item><title>Worst Presentation... Ever.</title><link>http://blogs.msdn.com/mwinkle/archive/2007/11/05/worst-presentation-ever.aspx</link><pubDate>Tue, 06 Nov 2007 02:12:52 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5921985</guid><dc:creator>mwinkle</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/mwinkle/comments/5921985.aspx</comments><wfw:commentRss>http://blogs.msdn.com/mwinkle/commentrss.aspx?PostID=5921985</wfw:commentRss><description>&lt;p&gt;I would like to take this moment to apologize for all of the attendees who were at our WIN302 session this afternoon here in Barcelona.&amp;#160; Moments before we were scheduled to begin, a very nasty power issue hit our room, causing the lights to go out, all of the equipment on stage to shut down, and reset all of the audio equipment (replaced with a series of rather nasty sounding &amp;quot;pops&amp;quot;.)&amp;#160; Our demo machine, which we had just spent the last few hours getting set &amp;quot;just so,&amp;quot; was also a casualty of this.&lt;/p&gt;  &lt;p&gt;Following 10 minutes of working with stage crews, audio techs, and David frantically trying to get the demo machine back to a usable state, we decided to begin the talk.&amp;#160; I had counted 5 minutes since someone ran down onto the stage yelling into a walkie talkie, so I figured we were in the clear.&lt;/p&gt;  &lt;p&gt;David was still working on the demo, so I began the talk, and quickly needed to fill time while David worked on the demo machine.&amp;#160; &lt;/p&gt;  &lt;p&gt;In short, by the time we got back to being ready, things were all jabberwockied up, and I was most certainly off my game, and as a result found myself rambling when I should have been focused, grasping for phrasing when I should have been driving the message, and stumbling in a talk where I had hoped to be knocking it out of the park.&lt;/p&gt;  &lt;p&gt;I want to apologize to the attendees, because you deserved a much better talk than the one you got (and David and I are going to make it up in part 2, tomorrow).&amp;#160; &lt;/p&gt;  &lt;p&gt;Reading through the feedback was pretty hard, this is a crowd that has very high expectations, and today did not meet that bar.&lt;/p&gt;  &lt;p&gt;Just when you think you have things all ready to go.&lt;/p&gt;  &lt;p&gt;How could we have done better?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A backup machine, set in exactly the same fashion as the first machine would have still not been particularly pleased with the power issue.&lt;/li&gt;    &lt;li&gt;I need a way to be able to save the state of all of my open visual studio windows and script out so I can run one script that opens all of the instances, and all of the right files (setting to the right spot would be nice as well).&lt;/li&gt;    &lt;li&gt;Not freaked out.&amp;#160; We had just gotten set and ready to go, and the power thing really knocked me off kilter.&amp;#160; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So, we walk away and we learn something, and we'll be back to do it again tomorrow.&amp;#160; Everyone has these nightmare conference stories, but that still doesn't make things better.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5921985" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/mwinkle/archive/tags/TechEd2007/default.aspx">TechEd2007</category><category domain="http://blogs.msdn.com/mwinkle/archive/tags/presentations/default.aspx">presentations</category></item></channel></rss>