<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>.NET Meanderings - WF</title>
    <link>http://www.dotnetconsult.co.uk/weblog2/</link>
    <description>Richard Blewett's wanderings around .NET</description>
    <language>en-us</language>
    <copyright>Richard Blewett</copyright>
    <lastBuildDate>Tue, 08 Jun 2010 09:52:40 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>richard@dotnetconsult.co.uk</managingEditor>
    <webMaster>richard@dotnetconsult.co.uk</webMaster>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=0cf7f2c1-78f5-43d6-820d-849d5cd5fee0</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0cf7f2c1-78f5-43d6-820d-849d5cd5fee0.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/SoftwareArchitectConference2010_98EF/Speaker_SA2010_120x120_4.jpg">
            <img style="border-right-width: 0px; margin: 0px 15px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Speaker_SA2010_120x120" border="0" alt="Speaker_SA2010_120x120" align="left" src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/SoftwareArchitectConference2010_98EF/Speaker_SA2010_120x120_thumb_1.jpg" width="124" height="124" />
          </a>
        </p>
        <p>
I’m speaking at Software Architect 2010 in October. I’m going to be delivering two
sessions on Windows Workflow Foundation 4.0: the first explains the basic architecture
and looks at using workflow as a Visual Scripting environment to empower business
users. The second looks at building big systems with workflow concentrating on the
WCF integration features. 
</p>
        <p>
In addition to that I’ll be delivering two all-day workshops with <a href="http://andyclymer.blogspot.com/">Andy
Clymer</a>: Building Applications the .NET 4.0 Way and Moving to the Parallel Mindset
with .NET 4.0. The first of these will take a number of new features of .NET 4.0 and
show how they can be combined to create compelling applications. The second will look
at the Parallel Framework Extensions (PFx) introduced in .NET 4.0 examining both the
rich functionality of the library, how it can be best leveraged avoiding common parallel
pitfalls and finally looking at patterns that aid parallelisation of your code
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=0cf7f2c1-78f5-43d6-820d-849d5cd5fee0" />
      </body>
      <title>Software Architect Conference 2010</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0cf7f2c1-78f5-43d6-820d-849d5cd5fee0.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0cf7f2c1-78f5-43d6-820d-849d5cd5fee0.aspx</link>
      <pubDate>Tue, 08 Jun 2010 09:52:40 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/SoftwareArchitectConference2010_98EF/Speaker_SA2010_120x120_4.jpg"&gt;&lt;img style="border-right-width: 0px; margin: 0px 15px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Speaker_SA2010_120x120" border="0" alt="Speaker_SA2010_120x120" align="left" src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/SoftwareArchitectConference2010_98EF/Speaker_SA2010_120x120_thumb_1.jpg" width="124" height="124"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
I’m speaking at Software Architect 2010 in October. I’m going to be delivering two
sessions on Windows Workflow Foundation 4.0: the first explains the basic architecture
and looks at using workflow as a Visual Scripting environment to empower business
users. The second looks at building big systems with workflow concentrating on the
WCF integration features. 
&lt;/p&gt;
&lt;p&gt;
In addition to that I’ll be delivering two all-day workshops with &lt;a href="http://andyclymer.blogspot.com/"&gt;Andy
Clymer&lt;/a&gt;: Building Applications the .NET 4.0 Way and Moving to the Parallel Mindset
with .NET 4.0. The first of these will take a number of new features of .NET 4.0 and
show how they can be combined to create compelling applications. The second will look
at the Parallel Framework Extensions (PFx) introduced in .NET 4.0 examining both the
rich functionality of the library, how it can be best leveraged avoiding common parallel
pitfalls and finally looking at patterns that aid parallelisation of your code
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=0cf7f2c1-78f5-43d6-820d-849d5cd5fee0" /&gt;</description>
      <category>.NET;PFx;RSK;WCF;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=0542f45a-40cc-4b2c-9bc4-b4b2740b2af4</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0542f45a-40cc-4b2c-9bc4-b4b2740b2af4.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Announced today at TechEd – Windows AppFabric is now available
</p>
        <p>
          <a href="http://blogs.msdn.com/b/endpoint/archive/2010/06/07/windows-server-appfabric-now-generally-available.aspx">http://blogs.msdn.com/b/endpoint/archive/2010/06/07/windows-server-appfabric-now-generally-available.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=0542f45a-40cc-4b2c-9bc4-b4b2740b2af4" />
      </body>
      <title>Windows AppFabric Hits the Streets</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0542f45a-40cc-4b2c-9bc4-b4b2740b2af4.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,0542f45a-40cc-4b2c-9bc4-b4b2740b2af4.aspx</link>
      <pubDate>Mon, 07 Jun 2010 21:05:40 GMT</pubDate>
      <description>&lt;p&gt;
Announced today at TechEd – Windows AppFabric is now available
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/b/endpoint/archive/2010/06/07/windows-server-appfabric-now-generally-available.aspx"&gt;http://blogs.msdn.com/b/endpoint/archive/2010/06/07/windows-server-appfabric-now-generally-available.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=0542f45a-40cc-4b2c-9bc4-b4b2740b2af4" /&gt;</description>
      <category>.NET;Dublin;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=332e063e-732b-45b7-a04b-2051785e0877</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,332e063e-732b-45b7-a04b-2051785e0877.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Rock Solid Knowledge on iTunes is live! We’ve taken the feed to our free screencasts
and they are now available through iTunes via the following link
</p>
        <p>
          <a href="http://itunes.apple.com/gb/podcast/rock-solid-knowledge-screencasts/id365244375">http://itunes.apple.com/gb/podcast/rock-solid-knowledge-screencasts/id365244375</a>
        </p>
        <p>
Now you can watch them on the move
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=332e063e-732b-45b7-a04b-2051785e0877" />
      </body>
      <title>Rock Solid Knowledge Screencasts now Available via iTunes</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,332e063e-732b-45b7-a04b-2051785e0877.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,332e063e-732b-45b7-a04b-2051785e0877.aspx</link>
      <pubDate>Tue, 30 Mar 2010 20:13:22 GMT</pubDate>
      <description>&lt;p&gt;
Rock Solid Knowledge on iTunes is live! We’ve taken the feed to our free screencasts
and they are now available through iTunes via the following link
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://itunes.apple.com/gb/podcast/rock-solid-knowledge-screencasts/id365244375"&gt;http://itunes.apple.com/gb/podcast/rock-solid-knowledge-screencasts/id365244375&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Now you can watch them on the move
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=332e063e-732b-45b7-a04b-2051785e0877" /&gt;</description>
      <category>.NET;EF4;PFx;RSK;SilverLight;WCF;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ab2a4f9a-b925-4903-8792-fb0a3bc3386c</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ab2a4f9a-b925-4903-8792-fb0a3bc3386c.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks to everyone who attended my sessions at DevWeek 2010. I’ve now uploaded the
demos which you can find at the following locations
</p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/demos/DevWeek2010DayOf4.0.zip">A
Day of .NET 4.0 Demos</a>
        </p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/demos/DevWeek2010WF4.zip">Windows
Workflow Foundation 4.0 Demos</a>
        </p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/demos/DevWeek2010WFServices.zip">Creating
WCF Services using WF4 Demos</a>
        </p>
        <p>
I’ll be around for the rest of the conference so drop by for a chat at our <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,93eeba3c-1dda-4f49-980d-03485fe9572e.aspx">developer
clinic</a> in the exhibition area
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ab2a4f9a-b925-4903-8792-fb0a3bc3386c" />
      </body>
      <title>Demos from DevWeek 2010</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ab2a4f9a-b925-4903-8792-fb0a3bc3386c.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ab2a4f9a-b925-4903-8792-fb0a3bc3386c.aspx</link>
      <pubDate>Wed, 17 Mar 2010 08:13:59 GMT</pubDate>
      <description>&lt;p&gt;
Thanks to everyone who attended my sessions at DevWeek 2010. I’ve now uploaded the
demos which you can find at the following locations
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/DevWeek2010DayOf4.0.zip"&gt;A
Day of .NET 4.0 Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/DevWeek2010WF4.zip"&gt;Windows
Workflow Foundation 4.0 Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/DevWeek2010WFServices.zip"&gt;Creating
WCF Services using WF4 Demos&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I’ll be around for the rest of the conference so drop by for a chat at our &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,93eeba3c-1dda-4f49-980d-03485fe9572e.aspx"&gt;developer
clinic&lt;/a&gt; in the exhibition area
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ab2a4f9a-b925-4903-8792-fb0a3bc3386c" /&gt;</description>
      <category>.NET;EF4;RSK;WCF;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ac4f4eaf-2b2d-475a-98b4-1bffb59b8e7b</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac4f4eaf-2b2d-475a-98b4-1bffb59b8e7b.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks to everyone who attended my two sessions at <a href="http://it-republik.de/dotnet/basta10spring/">BASTA!</a> –
another thoroughly enjoyable conference. I’ve uploaded the demos
</p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/downloads/BASTAWF4.zip">What’s
new in Workflow 4.0</a> – this includes the application with the rehosted designer
</p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/downloads/BASTAWFServices.zip">Building
WCF services with Workflow 4.0</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ac4f4eaf-2b2d-475a-98b4-1bffb59b8e7b" />
      </body>
      <title>Demos from BASTA!</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac4f4eaf-2b2d-475a-98b4-1bffb59b8e7b.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac4f4eaf-2b2d-475a-98b4-1bffb59b8e7b.aspx</link>
      <pubDate>Fri, 26 Feb 2010 10:02:42 GMT</pubDate>
      <description>&lt;p&gt;
Thanks to everyone who attended my two sessions at &lt;a href="http://it-republik.de/dotnet/basta10spring/"&gt;BASTA!&lt;/a&gt; –
another thoroughly enjoyable conference. I’ve uploaded the demos
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/downloads/BASTAWF4.zip"&gt;What’s
new in Workflow 4.0&lt;/a&gt; – this includes the application with the rehosted designer
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/downloads/BASTAWFServices.zip"&gt;Building
WCF services with Workflow 4.0&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ac4f4eaf-2b2d-475a-98b4-1bffb59b8e7b" /&gt;</description>
      <category>.NET;WCF;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=acafcfb9-2d8a-46d3-8a02-b4414e203cf8</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,acafcfb9-2d8a-46d3-8a02-b4414e203cf8.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I my <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c3394709-1aaf-486a-8d1f-51050ce94ecc.aspx">last
post</a> I showed that creating a custom composite activity (one that can have one
or more children) requires deriving from <font face="Courier New">NativeActivity</font>.
The <font face="Courier New">Retry</font> activity that I showed was fairly simple
and in particular didn’t try to share data with its child. There appears to be a <a href="http://en.wikipedia.org/wiki/Catch-22_(logic)">catch-22</a> in
this situation when it comes to overriding <font face="Courier New">CacheMetadata</font>:
if I add a <font face="Courier New">Variable</font> to the metadata (<font face="Courier New">AddVariable</font>)
then it can be used exclusively by its children – i.e. the activity itself can’t manipulate
the state; if I add a variable as implementation data to the metadata (<font face="Courier New">AddImplementationVariable</font>)
then the children cant see it as its seen as purely used for this activities implementation.
How then do we create data that can be both manipulated by the activity and accessed
by the parent?
</p>
        <p>
The secret to achieving this is a feature called <font face="Courier New">ActivityAction</font> - <a href="http://blogs.msdn.com/mwinkle/">Matt
Winkler</a> talks about it <a href="http://blogs.msdn.com/mwinkle/archive/2009/12/24/swiss-cheese-and-wf4-or-an-introduction-to-activityaction.aspx">here</a>.
The idea is that I can bind an activity to one or more parent defined pieces of data
then schedule the activity where it will have access to the data. Its probably best
to show this with an example so I have written a <font face="Courier New">ForEachFile</font> activity
that you give a directory and then it passes its child the file name of each file
in the directory in turn. I’ll show the code in its entirety and then walk through
each piece in turn 
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> [ContentProperty(<span style="color: #006080">"Body"</span>)]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> [Designer(<span style="color: #0000ff">typeof</span>(ForEachFileDesigner))]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">class</span> ForEachFile
: NativeActivity, IActivityTemplateFactory</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #0000ff">public</span> InArgument&lt;<span style="color: #0000ff">string</span>&gt;
Directory { get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> [Browsable(<span style="color: #0000ff">false</span>)]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #0000ff">public</span> ActivityAction&lt;<span style="color: #0000ff">string</span>&gt;
Body { get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
              <span style="color: #0000ff">private</span> Variable&lt;IEnumerator&lt;FileInfo&gt;&gt;
files = <span style="color: #0000ff">new</span> Variable&lt;IEnumerator&lt;FileInfo&gt;&gt;(<span style="color: #006080">"files"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">void</span> CacheMetadata(NativeActivityMetadata
metadata)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> metadata.AddDelegate(Body);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> RuntimeArgument
arg = <span style="color: #0000ff">new</span> RuntimeArgument(<span style="color: #006080">"Directory"</span>, <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>),
ArgumentDirection.In);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> metadata.AddArgument(arg);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span> metadata.AddImplementationVariable(files);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum21"> 21:</span>
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">void</span> Execute(NativeActivityContext
context)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum22"> 22:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum23"> 23:</span> DirectoryInfo
dir = <span style="color: #0000ff">new</span> DirectoryInfo(Directory.Get(context));</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum24"> 24:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum25"> 25:</span> IEnumerable&lt;FileInfo&gt;
fileEnum = dir.GetFiles();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum26"> 26:</span> IEnumerator&lt;FileInfo&gt;
fileList = fileEnum.GetEnumerator();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum27"> 27:</span> files.Set(context,
fileList);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum28"> 28:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum29"> 29:</span>
              <span style="color: #0000ff">bool</span> more
= fileList.MoveNext();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum30"> 30:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum31"> 31:</span>
              <span style="color: #0000ff">if</span> (more)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum32"> 32:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum33"> 33:</span> context.ScheduleAction&lt;<span style="color: #0000ff">string</span>&gt;(Body,
fileList.Current.FullName, OnBodyComplete);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum34"> 34:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum35"> 35:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum36"> 36:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum37"> 37:</span>
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">void</span> OnBodyComplete(
NativeActivityContext context, ActivityInstance completedInstance)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum38"> 38:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum39"> 39:</span> IEnumerator&lt;FileInfo&gt;
fileList = files.Get(context);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum40"> 40:</span>
              <span style="color: #0000ff">bool</span> more
= fileList.MoveNext();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum41"> 41:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum42"> 42:</span>
              <span style="color: #0000ff">if</span> (more)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum43"> 43:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum44"> 44:</span> context.ScheduleAction&lt;<span style="color: #0000ff">string</span>&gt;(Body,
fileList.Current.FullName, OnBodyComplete);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum45"> 45:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum46"> 46:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum47"> 47:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum48"> 48:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum49"> 49:</span>
              <span style="color: #cc6633">#region</span> IActivityTemplateFactory
Members</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum50"> 50:</span>
              <span style="color: #0000ff">public</span> Activity
Create(DependencyObject target)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum51"> 51:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum52"> 52:</span> var
fef = <span style="color: #0000ff">new</span> ForEachFile();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum53"> 53:</span> var
aa = <span style="color: #0000ff">new</span> ActivityAction&lt;<span style="color: #0000ff">string</span>&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum54"> 54:</span> var
da = <span style="color: #0000ff">new</span> DelegateInArgument&lt;<span style="color: #0000ff">string</span>&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum55"> 55:</span> da.Name
= <span style="color: #006080">"item"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum56"> 56:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum57"> 57:</span> fef.Body
= aa;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum58"> 58:</span> aa.Argument
= da;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum59"> 59:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum60"> 60:</span>
              <span style="color: #0000ff">return</span> fef;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum61"> 61:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum62"> 62:</span>
              <span style="color: #cc6633">#endregion</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum63"> 63:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
        </p>
        <p>
Ok lets start with the core functionality then we’ll look at each of the pieces that
help make this fully usable. As you can see the class derives from <font face="Courier New">NativeActivity</font> and
overrides <font face="Courier New">CacheMetadata</font> and <font face="Courier New">Execute</font> –
we’ll look at their implementations in a minute. There are three member variables
in the class: the <font face="Courier New">InArgument&lt;string&gt;</font> for the
directory; an implementation variable to hold the iterator as we move through the
files in the directory; the all important <font face="Courier New">ActivityAction&lt;string&gt;</font> which
we will use to pass the current file name to the child activity. 
</p>
        <p>
Lets look at <font face="Courier New">CacheMetadata</font> more closely. Because we
want to do interesting things with some of the state the default implementation won’t
work so we override it. As we don’t call the base class version we need to specify
how we use all of the state. We add the <font face="Courier New">ActivityAction</font> as
a delegate, we bind the <font face="Courier New">Directory</font> argument to a <font face="Courier New">RuntimeArgument</font> and
specify the iterator as an implementation variable – we don’t want the child activity
to have access to that directly.
</p>
        <p>
Next lets look at <font face="Courier New">Execute</font>. The first couple of lines
are nothing unusual – we get the directory and get hold of the list of files. Now
we have to store the retrieved iterator in the implementation variable, <font face="Courier New">fileList</font>.
We move to the first file in the iteration, if it returns <font face="Courier New">false</font> the
list was empty so as long as <font face="Courier New">MoveNext</font> returned <font face="Courier New">true</font> we
want to schedule the child activity passing the current file. To do this we use the <font face="Courier New">ScheduleAction&lt;T&gt;</font> member
on the context. However, because we’re going to process each one sequentially, we
also need to know when the child is finished so we pass a completion callback, <font face="Courier New">OnBodyComplete</font>.
</p>
        <p>
Now in <font face="Courier New">OnBodyComplete</font> we simply get the iterator,
move to the next item in the iteration and as long as we’re not finished iterating
re-schedule the child again passing the new item in the iteration.
</p>
        <p>
That really is the “functional” part of the activity – everything else is there to
support the designer. So why does the designer need help? Well lets look at what we
would have to do to build this activity correctly if we were going to execute it from
main
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> Activity
workflow = <span style="color: #0000ff">new</span> ForEachFile</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> Body
= <span style="color: #0000ff">new</span> ActivityAction&lt;<span style="color: #0000ff">string</span>&gt;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> Argument
= <span style="color: #0000ff">new</span> DelegateInArgument&lt;<span style="color: #0000ff">string</span>&gt;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> Name
= <span style="color: #006080">"item"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> },</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> Handler
= <span style="color: #0000ff">new</span> WriteLine</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span> Text
= <span style="color: #0000ff">new</span> VisualBasicValue&lt;<span style="color: #0000ff">string</span>&gt;(<span style="color: #006080">"item"</span>)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> },</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> Directory
= <span style="color: #006080">@"c:\windows"</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> };</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
        </p>
        <p>
As you can see, its not a matter of simply creating the <font face="Courier New">ForEachFile</font>,
we have to build the internal structure too – something needs to create that structure
for the designer - this is the point of <font face="Courier New">IActivityTemplateFactory</font>.
When you drag an activity on to the design surface normally it just creates the XAML
for that activity. However, before it does that it does a speculative cast for <font face="Courier New">IActivityTemplateFactory</font> and
if the activity supports that it calls the interface’s <font face="Courier New">Create</font> method
instead and serializes the resulting activity to XAML. 
</p>
        <p>
So going back to the <font face="Courier New">ForEachFile</font> activity, you can
see it implements <font face="Courier New">IActivityTemplateFactory</font> and therefore,
as far as the designer is concerned, this is the interesting functionality – lets
take a look at the <font face="Courier New">Create</font> method.We create the <font face="Courier New">ForEachFile</font> and
wire an <font face="Courier New">ActivityAction&lt;string&gt;</font> to its <font face="Courier New">Body</font> property. <font face="Courier New">ActivityAction&lt;string</font>&gt;
needs a slot to store the data to be presented to the child activity. This is modelled
by<font face="Courier New"> DelegateArgument&lt;string&gt;</font> and this gets wired
to the <font face="Courier New">Argument</font> member of the <font face="Courier New">ActvityAction</font>.
We also name the argument as we want a default name for the state so the child activity
can use it. Notice, however, we don’t specify the child activity itself (it would
be a pretty useless composite if we hard coded this). The child will be placed on
the <font face="Courier New">Handler</font> property of the <font face="Courier New">ActivityAction</font> but
that will be done in the <font face="Courier New">ActivityDesigner</font> using data
binding.
</p>
        <p>
Before we look at the designer lets highlight a couple of “polishing” features of
the code: the class declared a <font face="Courier New">ContentProperty</font> via
an attribute – that just makes the XAML parsing cleaner as the child doesn’t need
to be specified using <a href="http://msdn.microsoft.com/en-us/library/ms788723.aspx#PESyntax">property
element syntax</a>; the <font face="Courier New">Body</font> is set to non-browsable
– we don’t want the activities user to try to set this value in the property grid.
</p>
        <p>
OK on to the designer. If you read my previous article there are a couple of new things
here. Lets look at the markup – again there is no special code in the code behind
file, everything is achieved using data binding
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sap:ActivityDesigner</span>
              <span style="color: #ff0000">x:Class</span>
              <span style="color: #0000ff">="ActivityLib.ForEachFileDesigner"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #ff0000">xmlns</span>
              <span style="color: #0000ff">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #ff0000">xmlns:x</span>
              <span style="color: #0000ff">="http://schemas.microsoft.com/winfx/2006/xaml"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>
              <span style="color: #ff0000">xmlns:s</span>
              <span style="color: #0000ff">="clr-namespace:System;assembly=mscorlib"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #ff0000">xmlns:conv</span>
              <span style="color: #0000ff">="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>
              <span style="color: #ff0000">xmlns:sap</span>
              <span style="color: #0000ff">="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span>
              <span style="color: #ff0000">xmlns:sapv</span>
              <span style="color: #0000ff">="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #ff0000">xmlns:me</span>
              <span style="color: #0000ff">="clr-namespace:ActivityLib"</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sap:ActivityDesigner.Resources</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">conv:ArgumentToExpressionConverter</span>
              <span style="color: #ff0000">x:Key</span>
              <span style="color: #0000ff">="expressionConverter"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">sap:ActivityDesigner.Resources</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">Grid</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">Grid.RowDefinitions</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">RowDefinition</span>
              <span style="color: #ff0000">Height</span>
              <span style="color: #0000ff">="Auto"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">RowDefinition</span>
              <span style="color: #ff0000">Height</span>
              <span style="color: #0000ff">="*"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">Grid.RowDefinitions</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">StackPanel</span>
              <span style="color: #ff0000">Orientation</span>
              <span style="color: #0000ff">="Horizontal"</span>
              <span style="color: #ff0000">Margin</span>
              <span style="color: #0000ff">="2"</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">TextBlock</span>
              <span style="color: #ff0000">Text</span>
              <span style="color: #0000ff">="For
each file "</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum21"> 21:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">TextBox</span>
              <span style="color: #ff0000">Text</span>
              <span style="color: #0000ff">="{Binding
ModelItem.Body.Argument.Name}"</span>
              <span style="color: #ff0000">MinWidth</span>
              <span style="color: #0000ff">="50"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum22"> 22:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">TextBlock</span>
              <span style="color: #ff0000">Text</span>
              <span style="color: #0000ff">="
in "</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum23"> 23:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sapv:ExpressionTextBox</span>
              <span style="color: #ff0000">Expression</span>
              <span style="color: #0000ff">="{Binding
Path=ModelItem.Directory, Converter={StaticResource expressionConverter}}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum24"> 24:</span>
              <span style="color: #ff0000">ExpressionType</span>
              <span style="color: #0000ff">="s:String"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum25"> 25:</span>
              <span style="color: #ff0000">OwnerActivity</span>
              <span style="color: #0000ff">="{Binding
ModelItem}"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum26"> 26:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">StackPanel</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum27"> 27:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sap:WorkflowItemPresenter</span>
              <span style="color: #ff0000">Item</span>
              <span style="color: #0000ff">="{Binding
ModelItem.Body.Handler}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum28"> 28:</span>
              <span style="color: #ff0000">HintText</span>
              <span style="color: #0000ff">="Drop
activity"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum29"> 29:</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">Margin</span><span style="color: #0000ff">="6"</span><span style="color: #0000ff">/&gt;</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum30"> 30:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum31"> 31:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">Grid</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum32"> 32:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum33"> 33:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">sap:ActivityDesigner</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Here’s what this looks like in the designer
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/CreatingRichCompositeActivities_C385/ForEachFile_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="ForEachFile" border="0" alt="ForEachFile" src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/CreatingRichCompositeActivities_C385/ForEachFile_thumb.png" width="244" height="84" />
          </a>
        </p>
        <p>
So the TextBox at line 21 displays the argument name that our IActivityTemplateFactory
implementation set up. The ExpressionTextBox is bound to the directory name but allows
VB.NET expressions to be used. The WorkflowItemPresenter is bound to the Handler property
of the Body ActivityAction, This designer is then associated with the activity using
the [Designer] attribute.
</p>
        <p>
So as you can see, ActivityAction and IActivityTemplateFactory work together to allow
us to build rich composite activities with design time support
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=acafcfb9-2d8a-46d3-8a02-b4414e203cf8" />
      </body>
      <title>Creating Rich Composite Activities</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,acafcfb9-2d8a-46d3-8a02-b4414e203cf8.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,acafcfb9-2d8a-46d3-8a02-b4414e203cf8.aspx</link>
      <pubDate>Sun, 14 Feb 2010 13:54:30 GMT</pubDate>
      <description>&lt;p&gt;
I my &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c3394709-1aaf-486a-8d1f-51050ce94ecc.aspx"&gt;last
post&lt;/a&gt; I showed that creating a custom composite activity (one that can have one
or more children) requires deriving from &lt;font face="Courier New"&gt;NativeActivity&lt;/font&gt;.
The &lt;font face="Courier New"&gt;Retry&lt;/font&gt; activity that I showed was fairly simple
and in particular didn’t try to share data with its child. There appears to be a &lt;a href="http://en.wikipedia.org/wiki/Catch-22_(logic)"&gt;catch-22&lt;/a&gt; in
this situation when it comes to overriding &lt;font face="Courier New"&gt;CacheMetadata&lt;/font&gt;:
if I add a &lt;font face="Courier New"&gt;Variable&lt;/font&gt; to the metadata (&lt;font face="Courier New"&gt;AddVariable&lt;/font&gt;)
then it can be used exclusively by its children – i.e. the activity itself can’t manipulate
the state; if I add a variable as implementation data to the metadata (&lt;font face="Courier New"&gt;AddImplementationVariable&lt;/font&gt;)
then the children cant see it as its seen as purely used for this activities implementation.
How then do we create data that can be both manipulated by the activity and accessed
by the parent?
&lt;/p&gt;
&lt;p&gt;
The secret to achieving this is a feature called &lt;font face="Courier New"&gt;ActivityAction&lt;/font&gt; - &lt;a href="http://blogs.msdn.com/mwinkle/"&gt;Matt
Winkler&lt;/a&gt; talks about it &lt;a href="http://blogs.msdn.com/mwinkle/archive/2009/12/24/swiss-cheese-and-wf4-or-an-introduction-to-activityaction.aspx"&gt;here&lt;/a&gt;.
The idea is that I can bind an activity to one or more parent defined pieces of data
then schedule the activity where it will have access to the data. Its probably best
to show this with an example so I have written a &lt;font face="Courier New"&gt;ForEachFile&lt;/font&gt; activity
that you give a directory and then it passes its child the file name of each file
in the directory in turn. I’ll show the code in its entirety and then walk through
each piece in turn 
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; [ContentProperty(&lt;span style="color: #006080"&gt;"Body"&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; [Designer(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ForEachFileDesigner))]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ForEachFile
: NativeActivity, IActivityTemplateFactory&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
Directory { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; [Browsable(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActivityAction&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;
Body { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Variable&amp;lt;IEnumerator&amp;lt;FileInfo&amp;gt;&amp;gt;
files = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Variable&amp;lt;IEnumerator&amp;lt;FileInfo&amp;gt;&amp;gt;(&lt;span style="color: #006080"&gt;"files"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CacheMetadata(NativeActivityMetadata
metadata)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; metadata.AddDelegate(Body);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; RuntimeArgument
arg = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RuntimeArgument(&lt;span style="color: #006080"&gt;"Directory"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;),
ArgumentDirection.In);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; metadata.AddArgument(arg);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; metadata.AddImplementationVariable(files);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Execute(NativeActivityContext
context)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt; 22:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt; 23:&lt;/span&gt; DirectoryInfo
dir = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DirectoryInfo(Directory.Get(context));&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt; 24:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt; 25:&lt;/span&gt; IEnumerable&amp;lt;FileInfo&amp;gt;
fileEnum = dir.GetFiles();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt; 26:&lt;/span&gt; IEnumerator&amp;lt;FileInfo&amp;gt;
fileList = fileEnum.GetEnumerator();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt; 27:&lt;/span&gt; files.Set(context,
fileList);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt; 28:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt; 29:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; more
= fileList.MoveNext();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt; 30:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (more)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt; 32:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt; 33:&lt;/span&gt; context.ScheduleAction&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(Body,
fileList.Current.FullName, OnBodyComplete);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt; 34:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt; 35:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt; 36:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum37"&gt; 37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnBodyComplete(
NativeActivityContext context, ActivityInstance completedInstance)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum38"&gt; 38:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum39"&gt; 39:&lt;/span&gt; IEnumerator&amp;lt;FileInfo&amp;gt;
fileList = files.Get(context);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum40"&gt; 40:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; more
= fileList.MoveNext();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum41"&gt; 41:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum42"&gt; 42:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (more)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum43"&gt; 43:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum44"&gt; 44:&lt;/span&gt; context.ScheduleAction&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(Body,
fileList.Current.FullName, OnBodyComplete);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum45"&gt; 45:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum46"&gt; 46:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum47"&gt; 47:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum48"&gt; 48:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum49"&gt; 49:&lt;/span&gt; &lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; IActivityTemplateFactory
Members&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum50"&gt; 50:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Activity
Create(DependencyObject target)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum51"&gt; 51:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum52"&gt; 52:&lt;/span&gt; var
fef = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ForEachFile();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum53"&gt; 53:&lt;/span&gt; var
aa = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ActivityAction&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum54"&gt; 54:&lt;/span&gt; var
da = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DelegateInArgument&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum55"&gt; 55:&lt;/span&gt; da.Name
= &lt;span style="color: #006080"&gt;"item"&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum56"&gt; 56:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum57"&gt; 57:&lt;/span&gt; fef.Body
= aa;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum58"&gt; 58:&lt;/span&gt; aa.Argument
= da;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum59"&gt; 59:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum60"&gt; 60:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; fef;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum61"&gt; 61:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum62"&gt; 62:&lt;/span&gt; &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum63"&gt; 63:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Ok lets start with the core functionality then we’ll look at each of the pieces that
help make this fully usable. As you can see the class derives from &lt;font face="Courier New"&gt;NativeActivity&lt;/font&gt; and
overrides &lt;font face="Courier New"&gt;CacheMetadata&lt;/font&gt; and &lt;font face="Courier New"&gt;Execute&lt;/font&gt; –
we’ll look at their implementations in a minute. There are three member variables
in the class: the &lt;font face="Courier New"&gt;InArgument&amp;lt;string&amp;gt;&lt;/font&gt; for the
directory; an implementation variable to hold the iterator as we move through the
files in the directory; the all important &lt;font face="Courier New"&gt;ActivityAction&amp;lt;string&amp;gt;&lt;/font&gt; which
we will use to pass the current file name to the child activity. 
&lt;/p&gt;
&lt;p&gt;
Lets look at &lt;font face="Courier New"&gt;CacheMetadata&lt;/font&gt; more closely. Because we
want to do interesting things with some of the state the default implementation won’t
work so we override it. As we don’t call the base class version we need to specify
how we use all of the state. We add the &lt;font face="Courier New"&gt;ActivityAction&lt;/font&gt; as
a delegate, we bind the &lt;font face="Courier New"&gt;Directory&lt;/font&gt; argument to a &lt;font face="Courier New"&gt;RuntimeArgument&lt;/font&gt; and
specify the iterator as an implementation variable – we don’t want the child activity
to have access to that directly.
&lt;/p&gt;
&lt;p&gt;
Next lets look at &lt;font face="Courier New"&gt;Execute&lt;/font&gt;. The first couple of lines
are nothing unusual – we get the directory and get hold of the list of files. Now
we have to store the retrieved iterator in the implementation variable, &lt;font face="Courier New"&gt;fileList&lt;/font&gt;.
We move to the first file in the iteration, if it returns &lt;font face="Courier New"&gt;false&lt;/font&gt; the
list was empty so as long as &lt;font face="Courier New"&gt;MoveNext&lt;/font&gt; returned &lt;font face="Courier New"&gt;true&lt;/font&gt; we
want to schedule the child activity passing the current file. To do this we use the &lt;font face="Courier New"&gt;ScheduleAction&amp;lt;T&amp;gt;&lt;/font&gt; member
on the context. However, because we’re going to process each one sequentially, we
also need to know when the child is finished so we pass a completion callback, &lt;font face="Courier New"&gt;OnBodyComplete&lt;/font&gt;.
&lt;/p&gt;
&lt;p&gt;
Now in &lt;font face="Courier New"&gt;OnBodyComplete&lt;/font&gt; we simply get the iterator,
move to the next item in the iteration and as long as we’re not finished iterating
re-schedule the child again passing the new item in the iteration.
&lt;/p&gt;
&lt;p&gt;
That really is the “functional” part of the activity – everything else is there to
support the designer. So why does the designer need help? Well lets look at what we
would have to do to build this activity correctly if we were going to execute it from
main
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; Activity
workflow = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ForEachFile&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; Body
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ActivityAction&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; Argument
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DelegateInArgument&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; Name
= &lt;span style="color: #006080"&gt;"item"&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; },&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; Handler
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; WriteLine&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; Text
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; VisualBasicValue&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color: #006080"&gt;"item"&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; },&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; Directory
= &lt;span style="color: #006080"&gt;@"c:\windows"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; };&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, its not a matter of simply creating the &lt;font face="Courier New"&gt;ForEachFile&lt;/font&gt;,
we have to build the internal structure too – something needs to create that structure
for the designer - this is the point of &lt;font face="Courier New"&gt;IActivityTemplateFactory&lt;/font&gt;.
When you drag an activity on to the design surface normally it just creates the XAML
for that activity. However, before it does that it does a speculative cast for &lt;font face="Courier New"&gt;IActivityTemplateFactory&lt;/font&gt; and
if the activity supports that it calls the interface’s &lt;font face="Courier New"&gt;Create&lt;/font&gt; method
instead and serializes the resulting activity to XAML. 
&lt;/p&gt;
&lt;p&gt;
So going back to the &lt;font face="Courier New"&gt;ForEachFile&lt;/font&gt; activity, you can
see it implements &lt;font face="Courier New"&gt;IActivityTemplateFactory&lt;/font&gt; and therefore,
as far as the designer is concerned, this is the interesting functionality – lets
take a look at the &lt;font face="Courier New"&gt;Create&lt;/font&gt; method.We create the &lt;font face="Courier New"&gt;ForEachFile&lt;/font&gt; and
wire an &lt;font face="Courier New"&gt;ActivityAction&amp;lt;string&amp;gt;&lt;/font&gt; to its &lt;font face="Courier New"&gt;Body&lt;/font&gt; property. &lt;font face="Courier New"&gt;ActivityAction&amp;lt;string&lt;/font&gt;&amp;gt;
needs a slot to store the data to be presented to the child activity. This is modelled
by&lt;font face="Courier New"&gt; DelegateArgument&amp;lt;string&amp;gt;&lt;/font&gt; and this gets wired
to the &lt;font face="Courier New"&gt;Argument&lt;/font&gt; member of the &lt;font face="Courier New"&gt;ActvityAction&lt;/font&gt;.
We also name the argument as we want a default name for the state so the child activity
can use it. Notice, however, we don’t specify the child activity itself (it would
be a pretty useless composite if we hard coded this). The child will be placed on
the &lt;font face="Courier New"&gt;Handler&lt;/font&gt; property of the &lt;font face="Courier New"&gt;ActivityAction&lt;/font&gt; but
that will be done in the &lt;font face="Courier New"&gt;ActivityDesigner&lt;/font&gt; using data
binding.
&lt;/p&gt;
&lt;p&gt;
Before we look at the designer lets highlight a couple of “polishing” features of
the code: the class declared a &lt;font face="Courier New"&gt;ContentProperty&lt;/font&gt; via
an attribute – that just makes the XAML parsing cleaner as the child doesn’t need
to be specified using &lt;a href="http://msdn.microsoft.com/en-us/library/ms788723.aspx#PESyntax"&gt;property
element syntax&lt;/a&gt;; the &lt;font face="Courier New"&gt;Body&lt;/font&gt; is set to non-browsable
– we don’t want the activities user to try to set this value in the property grid.
&lt;/p&gt;
&lt;p&gt;
OK on to the designer. If you read my previous article there are a couple of new things
here. Lets look at the markup – again there is no special code in the code behind
file, everything is achieved using data binding
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Class&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="ActivityLib.ForEachFileDesigner"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:x&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:s&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System;assembly=mscorlib"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:conv&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:sap&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:sapv&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:me&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:ActivityLib"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;conv:ArgumentToExpressionConverter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="expressionConverter"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="*"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Orientation&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Horizontal"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="For
each file "&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
ModelItem.Body.Argument.Name}"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;MinWidth&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="50"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt; 22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Text&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="
in "&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sapv:ExpressionTextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Expression&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
Path=ModelItem.Directory, Converter={StaticResource expressionConverter}}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt; 24:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ExpressionType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="s:String"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt; 25:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OwnerActivity&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
ModelItem}"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt; 26:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;StackPanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:WorkflowItemPresenter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Item&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
ModelItem.Body.Handler}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt; 28:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HintText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Drop
activity"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt; 29:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="6"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt; 30:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt; 32:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt; 33:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Here’s what this looks like in the designer
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/CreatingRichCompositeActivities_C385/ForEachFile_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="ForEachFile" border="0" alt="ForEachFile" src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/CreatingRichCompositeActivities_C385/ForEachFile_thumb.png" width="244" height="84"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
So the TextBox at line 21 displays the argument name that our IActivityTemplateFactory
implementation set up. The ExpressionTextBox is bound to the directory name but allows
VB.NET expressions to be used. The WorkflowItemPresenter is bound to the Handler property
of the Body ActivityAction, This designer is then associated with the activity using
the [Designer] attribute.
&lt;/p&gt;
&lt;p&gt;
So as you can see, ActivityAction and IActivityTemplateFactory work together to allow
us to build rich composite activities with design time support
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=acafcfb9-2d8a-46d3-8a02-b4414e203cf8" /&gt;</description>
      <category>.NET;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=c3394709-1aaf-486a-8d1f-51050ce94ecc</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c3394709-1aaf-486a-8d1f-51050ce94ecc.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m writing <a href="http://www.develop.com/course/windows-workflow-foundation-csharp-4">Essential
Windows Workflow Foundation 4.0</a> with <a href="http://msmvps.com/blogs/theproblemsolver/default.aspx">Maurice</a> for <a href="http://www.develop.com">DevelopMentor</a>.
One of the things that I think is less than obvious is the behavior of NativeActivity.
</p>
        <p>
What is NativeActivity I hear you ask? Well there are a number of models for building
custom activities in WF4. Most “business” type custom activities will be built using
a declarative model in XAML by assembling building blocks graphically. However, what
if you are missing a building block? At this point you have to fall back to writing
code and there are three options for your base class when writing an activity in code:
</p>
        <p>
          <strong>
            <font size="2">CodeActivity</font>
          </strong>
          <br />
You use CodeActivity when you have a simple synchronous activity. All work happens
in Execute and it has no child activities
</p>
        <p>
          <strong>AsyncCodeActivity</strong>
          <br />
This is new to WF4. Here you have the ability to implement the async pattern (BeginExecute
/ EndExecute) to perform short lived async operations where you do not want the workflow
persisted (e.g. an async WebRequest)
</p>
        <p>
NativeActivity<br />
This gives you full access to the power of the workflow execution engine. However,
in the words of <a href="http://en.wikipedia.org/wiki/Uncle_Ben">Spiderman’s Uncle</a>,
“with great power comes great responsibility”. NativeActivity can be a bit tricky
so that is what this article is about
</p>
        <p>
I’m going to walk through the code for a Retry activity – where a child activity can
be rerun a number of times upon failure. The activity has two InArguments: <font face="Courier New">MaxRetries</font> and <font face="Courier New">RetryDelay</font>. <font face="Courier New">MaxRetries</font> says
how many times you will retry the child before giving up. <font face="Courier New">RetryDelay</font> says
how long to wait between retries. We could use a <font face="Courier New">Thread.Sleep</font> to
do the delay but this would not be good for the workflow engine: we block a thread
it could use and there is no way for the engine to persist the workflow – what if
we wanted to retry in 2 days? So instead, as part of our implementation, we’ll use
a <font face="Courier New">Delay</font> activity.
</p>
        <p>
Now to explain the code we have to take a slight diversion and talk about the relationship
between Activity, ActivityInstance and ExecutionContext. I talked about is a while
back <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,5a7759a2-c6c3-41f6-af58-ba4f82becc9a.aspx">here</a> when
the PDC CTP first came out (that’s what the reference to some base class called WorkflowElement
is about) but to expand a little: The Activity is really just a template containing
the code to execute for the activity. The ActivityInstance is the actual thing that
is executing. It holds the state for this instance of the activity template. Now we
need a way to bind the template code to the currently running instance of the activity
and this is the role of the ExecutionContext. If you are using a CodeActivity base
class then most of this is hidden from you except that you have to access arguments
by passing in the ExecutionContext. However, with NativeActivity you have to get more
directly involved with this model.
</p>
        <p>
Now how does the workflow engine know what data you need to store in the ActivityInstance?
Well it turns out you need to tell it. NativeActivity has a virtual method called
CacheMetadata (<a href="http://blogs.msdn.com/tilovell/archive/2010/02/06/nativeactivity-cachemetadata-for-fun-and-profit.aspx">this
post</a> talks about it to some degree). The point being that the activity has to
register all of the “stuff” that it wants to use during its execution. Now the base
class implementation will do some fairly reasonable default actions but it cannot
know, for example, that part of your functionality is there purely for implementation
details and should not be public. Therefore, you will often override this when you
create a NativeActivity
</p>
        <p>
So without more ado – here’s the code for the Retry activity. I’ll then walk through
it 
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> [Designer(<span style="color: #0000ff">typeof</span>(ForEachFileDesigner))]</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">class</span> Retry
: NativeActivity</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>
              <span style="color: #0000ff">public</span> InArgument&lt;<span style="color: #0000ff">int</span>&gt;
MaxRetries { get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #0000ff">public</span> InArgument&lt;TimeSpan&gt;
RetryDelay { get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>
              <span style="color: #0000ff">private</span> Delay
Delay = <span style="color: #0000ff">new</span> Delay();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #0000ff">public</span> Activity
Body { get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> Variable&lt;<span style="color: #0000ff">int</span>&gt;
CurrentRetry = <span style="color: #0000ff">new</span> Variable&lt;<span style="color: #0000ff">int</span>&gt;(<span style="color: #006080">"CurrentRetry"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">void</span> CacheMetadata(NativeActivityMetadata
metadata)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> metadata.AddChild(Body);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> metadata.AddImplementationVariable(CurrentRetry);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> RuntimeArgument
arg = <span style="color: #0000ff">new</span> RuntimeArgument(<span style="color: #006080">"MaxRetries"</span>, <span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">int</span>),
ArgumentDirection.In);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span> metadata.Bind(MaxRetries,
arg);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span> metadata.AddArgument(arg);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum21"> 21:</span> Delay.Duration
= RetryDelay;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum22"> 22:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum23"> 23:</span> metadata.AddImplementationChild(Delay);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum24"> 24:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum25"> 25:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum26"> 26:</span>
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">void</span> Execute(NativeActivityContext
context)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum27"> 27:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum28"> 28:</span> CurrentRetry.Set(context,
0);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum29"> 29:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum30"> 30:</span> context.ScheduleActivity(Body,
OnFaulted);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum31"> 31:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum32"> 32:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum33"> 33:</span>
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">void</span> OnFaulted(NativeActivityFaultContext
faultContext, Exception propagatedException, ActivityInstance propagatedFrom)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum34"> 34:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum35"> 35:</span>
              <span style="color: #0000ff">int</span> current
= CurrentRetry.Get(faultContext);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum36"> 36:</span>
              <span style="color: #0000ff">int</span> max
= MaxRetries.Get(faultContext);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum37"> 37:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum38"> 38:</span>
              <span style="color: #0000ff">if</span> (current
&lt; max)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum39"> 39:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum40"> 40:</span> faultContext.CancelChild(propagatedFrom);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum41"> 41:</span> faultContext.HandleFault();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum42"> 42:</span> faultContext.ScheduleActivity(Delay,
OnDelayComplete);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum43"> 43:</span> CurrentRetry.Set(faultContext,
current + 1);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum44"> 44:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum45"> 45:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum46"> 46:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum47"> 47:</span>
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">void</span> OnDelayComplete(NativeActivityContext
context, ActivityInstance completedInstance)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum48"> 48:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum49"> 49:</span> context.ScheduleActivity(Body,
OnFaulted);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum50"> 50:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum51"> 51:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
        </p>
        <p>
So lets look at the code: first the class derives from NativeActivity (we’ll come
to the designer later). This means I want to do fancy things like have child activities
or perform long running asynchronous work. Next we see the two InArguments that are
passed to the Retry. The Delay is an implementation detail of how we will pause between
retry attempts and the Body property is where the activity we are going to retry lives.
Finally we have a Variable, CurrentRetry, where we store how many retry attempts we
have made. That is the data in the class but remember we need to tell the workflow
engine about what we need to store and why – this is the point of CacheMetadata (I
read this method name as “here is the metadata for the cache” rather than “I am going
to cache some metadata”)
</p>
        <p>
In CacheMetadata the first thing we do is specify that the Body is our child activity.
Next we tell the engine that we want to be able to get hold of the CurrentRetry but
that its only there for our implementation – we’re not expecting the child activity
to try to make use of it. The next 3 lines (17-19) seem a little strange but essentially
we’re saying that the MaxRetries argument needs to be accessed over the whole lifetime
of the ActivityInstance so we need a slot for that. We next configure out Delay activity
passing the RetryDelay as its duration (this is how long we want to wait between retries).
Finally we add the Delay, not as a normal child, but as an implementation detail.
</p>
        <p>
OK, Execute is pretty simple – we initialize the CurrentRetry and then schedule the
Body. But, because we want to retry on failure, we also pass in a fault handler (OnFaulted)
</p>
        <p>
OnFaulted does the main work. It fires if the child fails. So it checks to see if
we have exceeded the retry count and if not retries the Body activity. However, it
doesn’t do this directly, first it tells the context that it has handled the error
– it also, strangely has to cancel the current child (which is odd as its already
faulted) – Maurice talks about this oddity <a href="http://msmvps.com/blogs/theproblemsolver/archive/2010/02/09/error-handling-in-a-nativeactivity.aspx">here</a>.
Next it schedules the Delay as we have to wait for the retry delay and wires up a
completion handler (OnDelayComplete) so we know when the delay is finished. Finally
it updates the CurrentRetry. 
</p>
        <p>
OnDelayComplete simply reschedules the Body activity, remembering to pass the fault
handler again in case the activity fails again.
</p>
        <p>
Oh one thing I said I’d come back to – the designer. I have written a designer to
go with this (designers in WF4 are WPF based). The XAML for this is here:
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sap:ActivityDesigner</span>
              <span style="color: #ff0000">x:Class</span>
              <span style="color: #0000ff">="WordActivities.ForEachFileDesigner"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #ff0000">xmlns</span>
              <span style="color: #0000ff">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #ff0000">xmlns:s</span>
              <span style="color: #0000ff">="clr-namespace:System;assembly=mscorlib"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>
              <span style="color: #ff0000">xmlns:x</span>
              <span style="color: #0000ff">="http://schemas.microsoft.com/winfx/2006/xaml"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #ff0000">xmlns:sap</span>
              <span style="color: #0000ff">="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>
              <span style="color: #ff0000">xmlns:sapv</span>
              <span style="color: #0000ff">="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span>
              <span style="color: #ff0000">xmlns:conv</span>
              <span style="color: #0000ff">="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #ff0000">mc:Ignorable</span>
              <span style="color: #0000ff">="d"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>
              <span style="color: #ff0000">xmlns:d</span>
              <span style="color: #0000ff">="http://schemas.microsoft.com/expression/blend/2008"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
              <span style="color: #ff0000">xmlns:mc</span>
              <span style="color: #0000ff">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sap:ActivityDesigner.Resources</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">conv:ArgumentToExpressionConverter</span>
              <span style="color: #ff0000">x:Key</span>
              <span style="color: #0000ff">="expressionConverter"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">sap:ActivityDesigner.Resources</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">Grid</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">Grid.RowDefinitions</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">RowDefinition</span>
              <span style="color: #ff0000">Height</span>
              <span style="color: #0000ff">="Auto"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">RowDefinition</span>
              <span style="color: #ff0000">Height</span>
              <span style="color: #0000ff">="Auto"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">RowDefinition</span>
              <span style="color: #ff0000">Height</span>
              <span style="color: #0000ff">="*"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">Grid.RowDefinitions</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">Grid.ColumnDefinitions</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum21"> 21:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">ColumnDefinition</span>
              <span style="color: #ff0000">Width</span>
              <span style="color: #0000ff">="Auto"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum22"> 22:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">ColumnDefinition</span>
              <span style="color: #ff0000">Width</span>
              <span style="color: #0000ff">="*"</span>
              <span style="color: #0000ff">/&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum23"> 23:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">Grid.ColumnDefinitions</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum24"> 24:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum25"> 25:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">TextBlock</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">Margin</span><span style="color: #0000ff">="2"</span><span style="color: #0000ff">&gt;</span>Max.
Retries:<span style="color: #0000ff">&lt;/</span><span style="color: #800000">TextBlock</span><span style="color: #0000ff">&gt;</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum26"> 26:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sapv:ExpressionTextBox</span>
              <span style="color: #ff0000">Expression</span>
              <span style="color: #0000ff">="{Binding
Path=ModelItem.MaxRetries, Converter={StaticResource expressionConverter}}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum27"> 27:</span>
              <span style="color: #ff0000">ExpressionType</span>
              <span style="color: #0000ff">="s:Int32"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum28"> 28:</span>
              <span style="color: #ff0000">OwnerActivity</span>
              <span style="color: #0000ff">="{Binding
ModelItem}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum29"> 29:</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">Margin</span><span style="color: #0000ff">="2"</span><span style="color: #0000ff">/&gt;</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum30"> 30:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum31"> 31:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">TextBlock</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">Margin</span><span style="color: #0000ff">="2"</span><span style="color: #0000ff">&gt;</span>Retry
Delay:<span style="color: #0000ff">&lt;/</span><span style="color: #800000">TextBlock</span><span style="color: #0000ff">&gt;</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum32"> 32:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sapv:ExpressionTextBox</span>
              <span style="color: #ff0000">Expression</span>
              <span style="color: #0000ff">="{Binding
Path=ModelItem.RetryDelay, Converter={StaticResource expressionConverter}}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum33"> 33:</span>
              <span style="color: #ff0000">ExpressionType</span>
              <span style="color: #0000ff">="s:TimeSpan"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum34"> 34:</span>
              <span style="color: #ff0000">OwnerActivity</span>
              <span style="color: #0000ff">="{Binding
ModelItem}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum35"> 35:</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">Margin</span><span style="color: #0000ff">="2"</span><span style="color: #0000ff">/&gt;</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum36"> 36:</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum37"> 37:</span>
              <span style="color: #0000ff">&lt;</span>
              <span style="color: #800000">sap:WorkflowItemPresenter</span>
              <span style="color: #ff0000">Item</span>
              <span style="color: #0000ff">="{Binding
ModelItem.Body}"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum38"> 38:</span>
              <span style="color: #ff0000">HintText</span>
              <span style="color: #0000ff">="Drop
Activity"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum39"> 39:</span>
              <span style="color: #ff0000">Margin</span>
              <span style="color: #0000ff">="6"</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum40"> 40:</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Row</span><span style="color: #0000ff">="2"</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum41"> 41:</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">Column</span><span style="color: #0000ff">="0"</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum42"> 42:</span>
              <span style="color: #ff0000">Grid</span>.<span style="color: #ff0000">ColumnSpan</span><span style="color: #0000ff">="2"</span><span style="color: #0000ff">/&gt;</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum43"> 43:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum44"> 44:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">Grid</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum45"> 45:</span>
              <span style="color: #0000ff">&lt;/</span>
              <span style="color: #800000">sap:ActivityDesigner</span>
              <span style="color: #0000ff">&gt;</span>
            </pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
There is no special code behind, everything is done via databinding. 
</p>
        <p>
So as you can see, there are a lot of pieces that need to be put into place for something
that seems fairly simple. The critical issue is getting the implementation of CacheMetadata
correct – once you have identified all of the pieces of data you need stored the rest
falls out nicely.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c3394709-1aaf-486a-8d1f-51050ce94ecc" />
      </body>
      <title>NativeActivity &amp;ndash; A Tricky Beast</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c3394709-1aaf-486a-8d1f-51050ce94ecc.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c3394709-1aaf-486a-8d1f-51050ce94ecc.aspx</link>
      <pubDate>Tue, 09 Feb 2010 20:14:03 GMT</pubDate>
      <description>&lt;p&gt;
I’m writing &lt;a href="http://www.develop.com/course/windows-workflow-foundation-csharp-4"&gt;Essential
Windows Workflow Foundation 4.0&lt;/a&gt; with &lt;a href="http://msmvps.com/blogs/theproblemsolver/default.aspx"&gt;Maurice&lt;/a&gt; for &lt;a href="http://www.develop.com"&gt;DevelopMentor&lt;/a&gt;.
One of the things that I think is less than obvious is the behavior of NativeActivity.
&lt;/p&gt;
&lt;p&gt;
What is NativeActivity I hear you ask? Well there are a number of models for building
custom activities in WF4. Most “business” type custom activities will be built using
a declarative model in XAML by assembling building blocks graphically. However, what
if you are missing a building block? At this point you have to fall back to writing
code and there are three options for your base class when writing an activity in code:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size="2"&gt;CodeActivity&lt;/font&gt;&lt;/strong&gt;
&lt;br&gt;
You use CodeActivity when you have a simple synchronous activity. All work happens
in Execute and it has no child activities
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;AsyncCodeActivity&lt;/strong&gt;
&lt;br&gt;
This is new to WF4. Here you have the ability to implement the async pattern (BeginExecute
/ EndExecute) to perform short lived async operations where you do not want the workflow
persisted (e.g. an async WebRequest)
&lt;/p&gt;
&lt;p&gt;
NativeActivity&lt;br&gt;
This gives you full access to the power of the workflow execution engine. However,
in the words of &lt;a href="http://en.wikipedia.org/wiki/Uncle_Ben"&gt;Spiderman’s Uncle&lt;/a&gt;,
“with great power comes great responsibility”. NativeActivity can be a bit tricky
so that is what this article is about
&lt;/p&gt;
&lt;p&gt;
I’m going to walk through the code for a Retry activity – where a child activity can
be rerun a number of times upon failure. The activity has two InArguments: &lt;font face="Courier New"&gt;MaxRetries&lt;/font&gt; and &lt;font face="Courier New"&gt;RetryDelay&lt;/font&gt;. &lt;font face="Courier New"&gt;MaxRetries&lt;/font&gt; says
how many times you will retry the child before giving up. &lt;font face="Courier New"&gt;RetryDelay&lt;/font&gt; says
how long to wait between retries. We could use a &lt;font face="Courier New"&gt;Thread.Sleep&lt;/font&gt; to
do the delay but this would not be good for the workflow engine: we block a thread
it could use and there is no way for the engine to persist the workflow – what if
we wanted to retry in 2 days? So instead, as part of our implementation, we’ll use
a &lt;font face="Courier New"&gt;Delay&lt;/font&gt; activity.
&lt;/p&gt;
&lt;p&gt;
Now to explain the code we have to take a slight diversion and talk about the relationship
between Activity, ActivityInstance and ExecutionContext. I talked about is a while
back &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,5a7759a2-c6c3-41f6-af58-ba4f82becc9a.aspx"&gt;here&lt;/a&gt; when
the PDC CTP first came out (that’s what the reference to some base class called WorkflowElement
is about) but to expand a little: The Activity is really just a template containing
the code to execute for the activity. The ActivityInstance is the actual thing that
is executing. It holds the state for this instance of the activity template. Now we
need a way to bind the template code to the currently running instance of the activity
and this is the role of the ExecutionContext. If you are using a CodeActivity base
class then most of this is hidden from you except that you have to access arguments
by passing in the ExecutionContext. However, with NativeActivity you have to get more
directly involved with this model.
&lt;/p&gt;
&lt;p&gt;
Now how does the workflow engine know what data you need to store in the ActivityInstance?
Well it turns out you need to tell it. NativeActivity has a virtual method called
CacheMetadata (&lt;a href="http://blogs.msdn.com/tilovell/archive/2010/02/06/nativeactivity-cachemetadata-for-fun-and-profit.aspx"&gt;this
post&lt;/a&gt; talks about it to some degree). The point being that the activity has to
register all of the “stuff” that it wants to use during its execution. Now the base
class implementation will do some fairly reasonable default actions but it cannot
know, for example, that part of your functionality is there purely for implementation
details and should not be public. Therefore, you will often override this when you
create a NativeActivity
&lt;/p&gt;
&lt;p&gt;
So without more ado – here’s the code for the Retry activity. I’ll then walk through
it 
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; [Designer(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ForEachFileDesigner))]&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Retry
: NativeActivity&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; InArgument&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt;
MaxRetries { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; InArgument&amp;lt;TimeSpan&amp;gt;
RetryDelay { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Delay
Delay = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Delay();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Activity
Body { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; Variable&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt;
CurrentRetry = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Variable&amp;lt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&amp;gt;(&lt;span style="color: #006080"&gt;"CurrentRetry"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; CacheMetadata(NativeActivityMetadata
metadata)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; metadata.AddChild(Body);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; metadata.AddImplementationVariable(CurrentRetry);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; RuntimeArgument
arg = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RuntimeArgument(&lt;span style="color: #006080"&gt;"MaxRetries"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;),
ArgumentDirection.In);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; metadata.Bind(MaxRetries,
arg);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; metadata.AddArgument(arg);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt; 21:&lt;/span&gt; Delay.Duration
= RetryDelay;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt; 22:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt; 23:&lt;/span&gt; metadata.AddImplementationChild(Delay);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt; 24:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt; 25:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt; 26:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Execute(NativeActivityContext
context)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt; 27:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt; 28:&lt;/span&gt; CurrentRetry.Set(context,
0);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt; 29:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt; 30:&lt;/span&gt; context.ScheduleActivity(Body,
OnFaulted);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt; 31:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt; 32:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt; 33:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnFaulted(NativeActivityFaultContext
faultContext, Exception propagatedException, ActivityInstance propagatedFrom)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt; 34:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt; 35:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; current
= CurrentRetry.Get(faultContext);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt; 36:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; max
= MaxRetries.Get(faultContext);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum37"&gt; 37:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum38"&gt; 38:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (current
&amp;lt; max)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum39"&gt; 39:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum40"&gt; 40:&lt;/span&gt; faultContext.CancelChild(propagatedFrom);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum41"&gt; 41:&lt;/span&gt; faultContext.HandleFault();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum42"&gt; 42:&lt;/span&gt; faultContext.ScheduleActivity(Delay,
OnDelayComplete);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum43"&gt; 43:&lt;/span&gt; CurrentRetry.Set(faultContext,
current + 1);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum44"&gt; 44:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum45"&gt; 45:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum46"&gt; 46:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum47"&gt; 47:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnDelayComplete(NativeActivityContext
context, ActivityInstance completedInstance)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum48"&gt; 48:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum49"&gt; 49:&lt;/span&gt; context.ScheduleActivity(Body,
OnFaulted);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum50"&gt; 50:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum51"&gt; 51:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
So lets look at the code: first the class derives from NativeActivity (we’ll come
to the designer later). This means I want to do fancy things like have child activities
or perform long running asynchronous work. Next we see the two InArguments that are
passed to the Retry. The Delay is an implementation detail of how we will pause between
retry attempts and the Body property is where the activity we are going to retry lives.
Finally we have a Variable, CurrentRetry, where we store how many retry attempts we
have made. That is the data in the class but remember we need to tell the workflow
engine about what we need to store and why – this is the point of CacheMetadata (I
read this method name as “here is the metadata for the cache” rather than “I am going
to cache some metadata”)
&lt;/p&gt;
&lt;p&gt;
In CacheMetadata the first thing we do is specify that the Body is our child activity.
Next we tell the engine that we want to be able to get hold of the CurrentRetry but
that its only there for our implementation – we’re not expecting the child activity
to try to make use of it. The next 3 lines (17-19) seem a little strange but essentially
we’re saying that the MaxRetries argument needs to be accessed over the whole lifetime
of the ActivityInstance so we need a slot for that. We next configure out Delay activity
passing the RetryDelay as its duration (this is how long we want to wait between retries).
Finally we add the Delay, not as a normal child, but as an implementation detail.
&lt;/p&gt;
&lt;p&gt;
OK, Execute is pretty simple – we initialize the CurrentRetry and then schedule the
Body. But, because we want to retry on failure, we also pass in a fault handler (OnFaulted)
&lt;/p&gt;
&lt;p&gt;
OnFaulted does the main work. It fires if the child fails. So it checks to see if
we have exceeded the retry count and if not retries the Body activity. However, it
doesn’t do this directly, first it tells the context that it has handled the error
– it also, strangely has to cancel the current child (which is odd as its already
faulted) – Maurice talks about this oddity &lt;a href="http://msmvps.com/blogs/theproblemsolver/archive/2010/02/09/error-handling-in-a-nativeactivity.aspx"&gt;here&lt;/a&gt;.
Next it schedules the Delay as we have to wait for the retry delay and wires up a
completion handler (OnDelayComplete) so we know when the delay is finished. Finally
it updates the CurrentRetry. 
&lt;/p&gt;
&lt;p&gt;
OnDelayComplete simply reschedules the Body activity, remembering to pass the fault
handler again in case the activity fails again.
&lt;/p&gt;
&lt;p&gt;
Oh one thing I said I’d come back to – the designer. I have written a designer to
go with this (designers in WF4 are WPF based). The XAML for this is here:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Class&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="WordActivities.ForEachFileDesigner"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:s&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System;assembly=mscorlib"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:x&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:sap&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:sapv&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:conv&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;mc:Ignorable&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="d"&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:d&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.microsoft.com/expression/blend/2008"&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;xmlns:mc&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="http://schemas.openxmlformats.org/markup-compatibility/2006"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;conv:ArgumentToExpressionConverter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;x:Key&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="expressionConverter"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner.Resources&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;RowDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="*"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.RowDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt; 21:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Auto"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt; 22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ColumnDefinition&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Width&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="*"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid.ColumnDefinitions&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt; 24:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt; 25:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Max.
Retries:&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt; 26:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sapv:ExpressionTextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Expression&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
Path=ModelItem.MaxRetries, Converter={StaticResource expressionConverter}}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt; 27:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ExpressionType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="s:Int32"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt; 28:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OwnerActivity&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
ModelItem}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt; 29:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt; 30:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Retry
Delay:&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;TextBlock&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt; 32:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sapv:ExpressionTextBox&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Expression&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
Path=ModelItem.RetryDelay, Converter={StaticResource expressionConverter}}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt; 33:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ExpressionType&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="s:TimeSpan"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt; 34:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;OwnerActivity&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
ModelItem}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt; 35:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt; 36:&lt;/span&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum37"&gt; 37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:WorkflowItemPresenter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Item&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="{Binding
ModelItem.Body}"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum38"&gt; 38:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;HintText&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="Drop
Activity"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum39"&gt; 39:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Margin&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="6"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum40"&gt; 40:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Row&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum41"&gt; 41:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;Column&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="0"&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum42"&gt; 42:&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Grid&lt;/span&gt;.&lt;span style="color: #ff0000"&gt;ColumnSpan&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="2"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum43"&gt; 43:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum44"&gt; 44:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;Grid&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum45"&gt; 45:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;sap:ActivityDesigner&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
There is no special code behind, everything is done via databinding. 
&lt;/p&gt;
&lt;p&gt;
So as you can see, there are a lot of pieces that need to be put into place for something
that seems fairly simple. The critical issue is getting the implementation of CacheMetadata
correct – once you have identified all of the pieces of data you need stored the rest
falls out nicely.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c3394709-1aaf-486a-8d1f-51050ce94ecc" /&gt;</description>
      <category>.NET;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=93eeba3c-1dda-4f49-980d-03485fe9572e</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,93eeba3c-1dda-4f49-980d-03485fe9572e.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve just noticed that <a href="http://andyclymer.blogspot.com/2010/02/ask-doctor-devweek-2010.html">Andy
has blogged</a> about our drop in clinic we are running at <a href="http://www.devweek.com/welcome.asp">DevWeek
2010</a>. All of the <a href="http://rocksolidknowledge.com/Home.mvc/us">Rock Solid
Knowledge guys</a> will be at the conference so come over and let us help solve your
design and coding problems – whether it be WCF, Workflow, Multithreading, WPF, Silverlight,
ASP.NET MVC,  Design Patterns or whatever you are currently wrestling with. We’re
also doing a bunch of talks (detailed on our <a href="http://rocksolidknowledge.com/Conferences.mvc/">Conferences
page</a>)
</p>
        <p>
          <a href="http://rocksolidknowledge.com/">
            <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DrRockman" border="0" alt="DrRockman" src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/DrRockmanisIN_BB50/DrRockman_3.png" width="144" height="244" />
          </a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=93eeba3c-1dda-4f49-980d-03485fe9572e" />
      </body>
      <title>Dr Rockman is IN!</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,93eeba3c-1dda-4f49-980d-03485fe9572e.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,93eeba3c-1dda-4f49-980d-03485fe9572e.aspx</link>
      <pubDate>Thu, 04 Feb 2010 13:19:44 GMT</pubDate>
      <description>&lt;p&gt;
I’ve just noticed that &lt;a href="http://andyclymer.blogspot.com/2010/02/ask-doctor-devweek-2010.html"&gt;Andy
has blogged&lt;/a&gt; about our drop in clinic we are running at &lt;a href="http://www.devweek.com/welcome.asp"&gt;DevWeek
2010&lt;/a&gt;. All of the &lt;a href="http://rocksolidknowledge.com/Home.mvc/us"&gt;Rock Solid
Knowledge guys&lt;/a&gt; will be at the conference so come over and let us help solve your
design and coding problems – whether it be WCF, Workflow, Multithreading, WPF, Silverlight,
ASP.NET MVC,&amp;nbsp; Design Patterns or whatever you are currently wrestling with. We’re
also doing a bunch of talks (detailed on our &lt;a href="http://rocksolidknowledge.com/Conferences.mvc/"&gt;Conferences
page&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.com/"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DrRockman" border="0" alt="DrRockman" src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WindowsLiveWriter/DrRockmanisIN_BB50/DrRockman_3.png" width="144" height="244"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=93eeba3c-1dda-4f49-980d-03485fe9572e" /&gt;</description>
      <category>.NET;RSK;WCF;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=67272417-08bb-4bb0-b01c-b91a44d0f433</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,67272417-08bb-4bb0-b01c-b91a44d0f433.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve just realised that <a href="http://www.devweek.com/">DevWeek 2010</a> is on the
horizon. DevWeek is one of my favourite conferences  - lots of varied talks,
vendor independence and I get to hang out with lots of friends for the week.
</p>
        <p>
This year I’m doing a preconference talk and two sessions:
</p>
        <p>
          <font size="4">A Day of .NET 4.0 
<br /></font>
          <font size="2">Mon 15th March 2010</font>
          <small>
            <br />
            <font size="2">
              <i>WORKSHOP REF: M1</i>
              <br />
.NET 4.0 is a major release of .NET, including the first big changes to the .NET runtime
since 2.0. In this series of talks we will look at the big changes in this release
in C#, multithreading, data access and workflow.<br />
The best-known change in C# is the introduction of dynamic typing. However, there
have been other changes that may affect your lives as developers more, such as support
for generic variance, named and optional parameters. There is a whole library for
multithreading, PFx, that not only assists you in parallelizing algorithms but in
fact replaces the existing libraries for multithreading with a unified, powerful single
API.<br />
Entity Framework has grown up – the initial release, although gaining some popularity,
missed features that made it truly usable in large-scale systems. The new release,
version 4.0, introduces a number of features, such as self-tracking objects, that
assist using Entity Framework in n-tier applications.<br />
Finally, workflow gets a total rewrite to allow the engine to be used far more widely,
having overcome limitations in the WF 3.5 API.<br />
This workshop will take you through all of these major changes, and we’ll also talk
about some of the other smaller but important ones along the way.</font>
          </small>
        </p>
        <p>
          <small>
            <font size="2">
            </font>
          </small>
          <small>
            <font size="2">
              <font size="4">An Introduction
to Windows Workflow Foundation 4.0</font>
              <br />
Tues 16th March 2010<small><br /></small>.NET 4.0 introduces a new version of Windows Workflow Foundation. This new
version is a total rewrite of the version introduced with .NET 3.0. In this talk we
look at what Microsoft are trying to achieve with WF 4.0, why they felt it necessary
to rewrite rather than modify the codebase, and what new features are available in
the new library. Along the way we will be looking at the new designer, declarative
workflows, asynchronous processing, sequential and flowchart workflows and how workflow’s
automated persistence works.</font>
          </small>
        </p>
        <p>
          <small>
            <font size="2">
              <font size="4">Creating Workflow-based WCF Services<br /></font>Tues 16th March 2010<br /></font>
          </small>
          <small>
            <font size="2">There are very good reasons for using a workflow
to implement a WCF service: workflows can provide a clear platform for service composition
(using a number of building block services to generate a functionally richer service);
workflow can manage long running stateful services without having to write your own
plumbing to achieve this. The latest version of Workflow, 4.0, introduces a declarative
model for authoring workflows and new activities for message based interaction. In
addition we have a framework for flexible message correlation that allows the contents
of a message to determine which workflow the message is destined for. In this session
we will look at how you can consume services from workflow and expose the resulting
workflow itself as a service.</font>
          </small>
        </p>
        <p>
          <small>
            <font size="2">As well as these you may well see me popping up as a guest code-monkey
in the other <a href="http://rocksolidknowledge.com/Conferences.mvc/">Rock Solid Knowledge</a> sessions.
Hope to see you there</font>
          </small>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=67272417-08bb-4bb0-b01c-b91a44d0f433" />
      </body>
      <title>DevWeek on the Horizon</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,67272417-08bb-4bb0-b01c-b91a44d0f433.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,67272417-08bb-4bb0-b01c-b91a44d0f433.aspx</link>
      <pubDate>Mon, 18 Jan 2010 14:52:19 GMT</pubDate>
      <description>&lt;p&gt;
I’ve just realised that &lt;a href="http://www.devweek.com/"&gt;DevWeek 2010&lt;/a&gt; is on the
horizon. DevWeek is one of my favourite conferences&amp;nbsp; - lots of varied talks,
vendor independence and I get to hang out with lots of friends for the week.
&lt;/p&gt;
&lt;p&gt;
This year I’m doing a preconference talk and two sessions:
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;A Day of .NET 4.0 
&lt;br&gt;
&lt;/font&gt;&lt;font size="2"&gt;Mon 15th March 2010&lt;/font&gt;&lt;small&gt;
&lt;br&gt;
&lt;font size="2"&gt;&lt;i&gt;WORKSHOP REF: M1&lt;/i&gt;
&lt;br&gt;
.NET 4.0 is a major release of .NET, including the first big changes to the .NET runtime
since 2.0. In this series of talks we will look at the big changes in this release
in C#, multithreading, data access and workflow.&lt;br&gt;
The best-known change in C# is the introduction of dynamic typing. However, there
have been other changes that may affect your lives as developers more, such as support
for generic variance, named and optional parameters. There is a whole library for
multithreading, PFx, that not only assists you in parallelizing algorithms but in
fact replaces the existing libraries for multithreading with a unified, powerful single
API.&lt;br&gt;
Entity Framework has grown up – the initial release, although gaining some popularity,
missed features that made it truly usable in large-scale systems. The new release,
version 4.0, introduces a number of features, such as self-tracking objects, that
assist using Entity Framework in n-tier applications.&lt;br&gt;
Finally, workflow gets a total rewrite to allow the engine to be used far more widely,
having overcome limitations in the WF 3.5 API.&lt;br&gt;
This workshop will take you through all of these major changes, and we’ll also talk
about some of the other smaller but important ones along the way.&lt;/font&gt;&lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;small&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/small&gt;&lt;small&gt;&lt;font size="2"&gt;&lt;font size="4"&gt;An Introduction
to Windows Workflow Foundation 4.0&lt;/font&gt;
&lt;br&gt;
Tues 16th March 2010&lt;small&gt;
&lt;br&gt;
&lt;/small&gt;.NET 4.0 introduces a new version of Windows Workflow Foundation. This new
version is a total rewrite of the version introduced with .NET 3.0. In this talk we
look at what Microsoft are trying to achieve with WF 4.0, why they felt it necessary
to rewrite rather than modify the codebase, and what new features are available in
the new library. Along the way we will be looking at the new designer, declarative
workflows, asynchronous processing, sequential and flowchart workflows and how workflow’s
automated persistence works.&lt;/font&gt;&lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;small&gt;&lt;font size="2"&gt;&lt;font size="4"&gt;Creating Workflow-based WCF Services&lt;br&gt;
&lt;/font&gt;Tues 16th March 2010&lt;br&gt;
&lt;/font&gt;&lt;/small&gt;&lt;small&gt;&lt;font size="2"&gt;There are very good reasons for using a workflow
to implement a WCF service: workflows can provide a clear platform for service composition
(using a number of building block services to generate a functionally richer service);
workflow can manage long running stateful services without having to write your own
plumbing to achieve this. The latest version of Workflow, 4.0, introduces a declarative
model for authoring workflows and new activities for message based interaction. In
addition we have a framework for flexible message correlation that allows the contents
of a message to determine which workflow the message is destined for. In this session
we will look at how you can consume services from workflow and expose the resulting
workflow itself as a service.&lt;/font&gt;&lt;/small&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;small&gt;&lt;font size="2"&gt;As well as these you may well see me popping up as a guest code-monkey
in the other &lt;a href="http://rocksolidknowledge.com/Conferences.mvc/"&gt;Rock Solid Knowledge&lt;/a&gt; sessions.
Hope to see you there&lt;/font&gt;&lt;/small&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=67272417-08bb-4bb0-b01c-b91a44d0f433" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=3c481d20-caf5-49c7-9b6a-aa3c9a5663bd</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,3c481d20-caf5-49c7-9b6a-aa3c9a5663bd.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Seeing as this has changed completely from WF 3.5 I thought I’d post a quick blog
entry to describe how to run a workflow declared in a XAML file.
</p>
        <p>
You may have heard that the WF 4.0 default authoring model is now XAML. However, the
Visual Studio 2010 workflow projects store the XAML as a resource in the binary rather
than as a text file. So if you want to deploy your workflows as XAML text files how
do you run them? In .NET 3.5 you could pass the workflow runtime an <font face="Courier New">XmlReader</font> pointing
at the XAML file but in WF 4.0 there is no <font face="Courier New">WorkflowRuntime</font> class.
It turns out you need to load the XAML slightly indirectly by creating a special activity
called a <font face="Courier New">DynamicActivity</font></p>
        <p>
          <font face="Courier New">DynamicActivity</font> has an <font face="Courier New">Implementation</font> member
that points to a <font face="Courier New">Func&lt;Activity&gt;</font> delegate – in
other words you wire up a method that returns an activity (the workflow). Here’s an
example:
</p>
        <div id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">static</span>
              <span style="color: #0000ff">void</span> Main(<span style="color: #0000ff">string</span>[]
args)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">  DynamicActivity dyn = <span style="color: #0000ff">new</span> DynamicActivity();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #008000">//
this line wires up the workflow creator method</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">  dyn.Implementation = CreateWorkflow;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">  WorkflowInvoker.Invoke(dyn);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">static</span> Activity
CreateWorkflow()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">{</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #008000">//
we use the new XamlServices utility class to deserialize the XAML</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">  Activity act = (Activity)XamlServices.Load(<span style="color: #006080">@"..\..\workflow1.xaml"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"> </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
              <span style="color: #0000ff">return</span> act;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">}</pre>
            <!--CRLF-->
          </div>
        </div>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=3c481d20-caf5-49c7-9b6a-aa3c9a5663bd" />
      </body>
      <title>Executing Workflows from XAML Files</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,3c481d20-caf5-49c7-9b6a-aa3c9a5663bd.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,3c481d20-caf5-49c7-9b6a-aa3c9a5663bd.aspx</link>
      <pubDate>Thu, 17 Dec 2009 16:27:07 GMT</pubDate>
      <description>&lt;p&gt;
Seeing as this has changed completely from WF 3.5 I thought I’d post a quick blog
entry to describe how to run a workflow declared in a XAML file.
&lt;/p&gt;
&lt;p&gt;
You may have heard that the WF 4.0 default authoring model is now XAML. However, the
Visual Studio 2010 workflow projects store the XAML as a resource in the binary rather
than as a text file. So if you want to deploy your workflows as XAML text files how
do you run them? In .NET 3.5 you could pass the workflow runtime an &lt;font face="Courier New"&gt;XmlReader&lt;/font&gt; pointing
at the XAML file but in WF 4.0 there is no &lt;font face="Courier New"&gt;WorkflowRuntime&lt;/font&gt; class.
It turns out you need to load the XAML slightly indirectly by creating a special activity
called a &lt;font face="Courier New"&gt;DynamicActivity&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;DynamicActivity&lt;/font&gt; has an &lt;font face="Courier New"&gt;Implementation&lt;/font&gt; member
that points to a &lt;font face="Courier New"&gt;Func&amp;lt;Activity&amp;gt;&lt;/font&gt; delegate – in
other words you wire up a method that returns an activity (the workflow). Here’s an
example:
&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
args)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  DynamicActivity dyn = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicActivity();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #008000"&gt;//
this line wires up the workflow creator method&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  dyn.Implementation = CreateWorkflow;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  WorkflowInvoker.Invoke(dyn);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt; Activity
CreateWorkflow()&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #008000"&gt;//
we use the new XamlServices utility class to deserialize the XAML&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  Activity act = (Activity)XamlServices.Load(&lt;span style="color: #006080"&gt;@"..\..\workflow1.xaml"&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; act;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=3c481d20-caf5-49c7-9b6a-aa3c9a5663bd" /&gt;</description>
      <category>.NET;WF;WF4</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=51443278-6c7c-4eba-8335-075d97b9f66d</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,51443278-6c7c-4eba-8335-075d97b9f66d.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just got back from speaking at <a href="http://www.software-architect.co.uk/">Software
Architect 2009</a>. I had a great time at the conference and thanks to everyone who
attended my sessions. As promised the slides and demos are now available on the <a href="http://rocksolidknowledge.com">Rock
Solid Knowledge</a> website and you can get them from the <a href="http://rocksolidknowledge.com/Conferences.mvc/">Conferences</a> page.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=51443278-6c7c-4eba-8335-075d97b9f66d" />
      </body>
      <title>Slides and Demos from Software Architect 2009 are now available</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,51443278-6c7c-4eba-8335-075d97b9f66d.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,51443278-6c7c-4eba-8335-075d97b9f66d.aspx</link>
      <pubDate>Fri, 02 Oct 2009 21:12:18 GMT</pubDate>
      <description>&lt;p&gt;
I just got back from speaking at &lt;a href="http://www.software-architect.co.uk/"&gt;Software
Architect 2009&lt;/a&gt;. I had a great time at the conference and thanks to everyone who
attended my sessions. As promised the slides and demos are now available on the &lt;a href="http://rocksolidknowledge.com"&gt;Rock
Solid Knowledge&lt;/a&gt; website and you can get them from the &lt;a href="http://rocksolidknowledge.com/Conferences.mvc/"&gt;Conferences&lt;/a&gt; page.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=51443278-6c7c-4eba-8335-075d97b9f66d" /&gt;</description>
      <category>.NET;Azure;REST;RSK;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=539cffbc-01e3-4079-a6e3-738c3a3b29ed</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,539cffbc-01e3-4079-a6e3-738c3a3b29ed.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks to everyone who came to my sessions at <a href="http://it-republik.de/dotnet/basta09/micro">BASTA!</a> My
first time at that conference and I had a great time. Here are the slides and demos
</p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/demos/BastaWF4.zip?timeout=300">What’s
New in Workflow 4.0</a>
        </p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/demos/BastaContractFirst.zip?timeout=300">Contract
First Development with WCF</a>
        </p>
        <p>
          <a href="http://rocksolidknowledge.blob.core.windows.net/demos/BastaBeyondListOfT.zip?timeout=300">Generics,
Extension Methods and Lambdas – Beyond List&lt;T&gt;</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=539cffbc-01e3-4079-a6e3-738c3a3b29ed" />
      </body>
      <title>Slides and Demos from BASTA!</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,539cffbc-01e3-4079-a6e3-738c3a3b29ed.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,539cffbc-01e3-4079-a6e3-738c3a3b29ed.aspx</link>
      <pubDate>Sat, 26 Sep 2009 08:24:56 GMT</pubDate>
      <description>&lt;p&gt;
Thanks to everyone who came to my sessions at &lt;a href="http://it-republik.de/dotnet/basta09/micro"&gt;BASTA!&lt;/a&gt; My
first time at that conference and I had a great time. Here are the slides and demos
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/BastaWF4.zip?timeout=300"&gt;What’s
New in Workflow 4.0&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/BastaContractFirst.zip?timeout=300"&gt;Contract
First Development with WCF&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/BastaBeyondListOfT.zip?timeout=300"&gt;Generics,
Extension Methods and Lambdas – Beyond List&amp;lt;T&amp;gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=539cffbc-01e3-4079-a6e3-738c3a3b29ed" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=2fee98c4-abb6-455e-a738-47f286bfaf51</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Every year I speak at the excellent <a href="http://www.devweek.com/">DevWeek</a> conference
in London. <a href="http://geekswithblogs.net/iupdateable/Default.aspx">Eric Nelson</a>,
a Microsoft Developer Evangelist in the UK is also a regular attendee. This year Eric, <a href="http://mtaulty.com/communityserver/blogs/mike_taultys_blog/default.aspx">Mike</a> and <a href="http://blogs.msdn.com/mikeormond/">Mike</a> were
recording interviews with people at the conference. Eric interviewed me about Workflow
4.0 (I was delivering a post conference day on WF 4.0, Dublin and Oslo). He’s just
got round to published it online
</p>
        <p>
          <a href="http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx">http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2fee98c4-abb6-455e-a738-47f286bfaf51" />
      </body>
      <title>DevWeek Interview Online</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2fee98c4-abb6-455e-a738-47f286bfaf51.aspx</link>
      <pubDate>Thu, 21 May 2009 05:49:02 GMT</pubDate>
      <description>&lt;p&gt;
Every year I speak at the excellent &lt;a href="http://www.devweek.com/"&gt;DevWeek&lt;/a&gt; conference
in London. &lt;a href="http://geekswithblogs.net/iupdateable/Default.aspx"&gt;Eric Nelson&lt;/a&gt;,
a Microsoft Developer Evangelist in the UK is also a regular attendee. This year Eric, &lt;a href="http://mtaulty.com/communityserver/blogs/mike_taultys_blog/default.aspx"&gt;Mike&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/mikeormond/"&gt;Mike&lt;/a&gt; were
recording interviews with people at the conference. Eric interviewed me about Workflow
4.0 (I was delivering a post conference day on WF 4.0, Dublin and Oslo). He’s just
got round to published it online
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx"&gt;http://geekswithblogs.net/iupdateable/archive/2009/05/20/devweek-2009-interview-with-richard-blewett-on-workflow-4.0.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2fee98c4-abb6-455e-a738-47f286bfaf51" /&gt;</description>
      <category>.NET;Dublin;Oslo;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=06c841b2-52b8-473a-8168-b063b3a24b34</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Soma has blogged that beta 1 has finally shipped. Lots of new stuff in here since
PDC. His blog post is here
</p>
        <p>
          <a href="http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx">http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=06c841b2-52b8-473a-8168-b063b3a24b34" />
      </body>
      <title>Visual Studio 2010 Beta 1 Ships</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,06c841b2-52b8-473a-8168-b063b3a24b34.aspx</link>
      <pubDate>Mon, 18 May 2009 15:06:32 GMT</pubDate>
      <description>&lt;p&gt;
Soma has blogged that beta 1 has finally shipped. Lots of new stuff in here since
PDC. His blog post is here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx"&gt;http://blogs.msdn.com/somasegar/archive/2009/05/18/visual-studio-2010-and-net-fx-4-beta-1-ships.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=06c841b2-52b8-473a-8168-b063b3a24b34" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Cliff Simpkins has just <a href="http://blogs.msdn.com/endpoint/archive/2009/05/01/the-road-to-4-wf-changes-between-beta-1-and-ctp.aspx">posted
a blog entry</a> detailing some of the changes between the PDC preview of WF 4.0 and
what is coming in beta 1, due shortly. 
</p>
        <p>
Important information here not just about beta 1 but also about things you can expect
and also things that won’t make it into RTM
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e" />
      </body>
      <title>What&amp;rsquo;s new in WF 4.0 Beta 1</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ac27a12b-23a9-4154-b3e1-4c1c27e26c1e.aspx</link>
      <pubDate>Fri, 01 May 2009 23:27:00 GMT</pubDate>
      <description>&lt;p&gt;
Cliff Simpkins has just &lt;a href="http://blogs.msdn.com/endpoint/archive/2009/05/01/the-road-to-4-wf-changes-between-beta-1-and-ctp.aspx"&gt;posted
a blog entry&lt;/a&gt; detailing some of the changes between the PDC preview of WF 4.0 and
what is coming in beta 1, due shortly. 
&lt;/p&gt;
&lt;p&gt;
Important information here not just about beta 1 but also about things you can expect
and also things that won’t make it into RTM
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ac27a12b-23a9-4154-b3e1-4c1c27e26c1e" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=db4d4d38-b469-4181-aead-f8de85f39b80</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks all who attended my post conference day on a day of connected systems with
.NET 4.0, Dublin and Oslo. You can get the demos <a href="http://rocksolidknowledge.blob.core.windows.net/demos/Devweek2009DayOfCSD.zip">here</a>.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=db4d4d38-b469-4181-aead-f8de85f39b80" />
      </body>
      <title>Devweek 2009: A Day Connected Systems Demos</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,db4d4d38-b469-4181-aead-f8de85f39b80.aspx</link>
      <pubDate>Sat, 28 Mar 2009 08:39:03 GMT</pubDate>
      <description>&lt;p&gt;
Thanks all who attended my post conference day on a day of connected systems with
.NET 4.0, Dublin and Oslo. You can get the demos &lt;a href="http://rocksolidknowledge.blob.core.windows.net/demos/Devweek2009DayOfCSD.zip"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=db4d4d38-b469-4181-aead-f8de85f39b80" /&gt;</description>
      <category>Dublin;Oslo;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=76bd58e0-39e7-4624-b3af-b6794d047cef</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks to all who attended my <a href="www.devweek.com">Devweek</a> session: A Beginners
Guide to Windows Workflow. The slides and demos can be downloaded <a href="http://dotnetconsult.blob.core.windows.net/demos/WorkflowForBeginners.zip">here</a></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=76bd58e0-39e7-4624-b3af-b6794d047cef" />
      </body>
      <title>Slides and demos from my Windows Workflow Session at Devweek</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,76bd58e0-39e7-4624-b3af-b6794d047cef.aspx</link>
      <pubDate>Thu, 26 Mar 2009 06:51:37 GMT</pubDate>
      <description>&lt;p&gt;
Thanks to all who attended my &lt;a href="www.devweek.com"&gt;Devweek&lt;/a&gt; session: A Beginners
Guide to Windows Workflow. The slides and demos can be downloaded &lt;a href="http://dotnetconsult.blob.core.windows.net/demos/WorkflowForBeginners.zip"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=76bd58e0-39e7-4624-b3af-b6794d047cef" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=5a7759a2-c6c3-41f6-af58-ba4f82becc9a</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,5a7759a2-c6c3-41f6-af58-ba4f82becc9a.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I talked about the new <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx">WF4
Runtime model</a> a while back. One of the things I discussed was the new data flow
model of arguments and variables. However, if you are used to WF 3.5 something looks
a bit odd here. Lets look at a simple activity example:
</p>
        <p>
          <span style="font-size: 11px; color: black; font-family: courier new; background-color: transparent">
            <span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">public</span>
            <span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">class</span> WriteLineActivity
: WorkflowElement<br />
{<br /><span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">   
public</span><strong>InArgument&lt;<span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">string</span>&gt;
Text</strong> { get; set; }<br /><span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">   
protected</span><span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">override</span><span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent">void</span> Execute(ActivityExecutionContext
context)<br />
    {<br />
        Console.WriteLine(<strong>Text.Get(context)</strong>);<br />
    }<br />
}</span>
        </p>
        <p>
          <span style="font-size: 11px; color: black; font-family: courier new; background-color: transparent">
            <font face="Trebuchet MS" size="2">Why
do I need to pass the ActivityExecutionContext when I want to get the data from the
argument? This highlights a subtlety to the change in the runtime model. The activity
is really just a template. A class called ActivityInstance is the thing that is actually
executed, it just has a reference to the actual activity to be able to hand off to
the activty’s methods (e.g. Execute). The actual argument state is stored in a construct
called the LocalEnvironment. The ActivityExecutionContext gives access to  the
current ActivityInstance and that in turn holds a reference to the current LocalEnvironment.
Therefore, to get from  an activity’s Execute method to its state we have to
go via the ActivityExecutionContext.<br /></font>
          </span>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=5a7759a2-c6c3-41f6-af58-ba4f82becc9a" />
      </body>
      <title>WF4: Why do I have to pass the context to get data from an argument?</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,5a7759a2-c6c3-41f6-af58-ba4f82becc9a.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,5a7759a2-c6c3-41f6-af58-ba4f82becc9a.aspx</link>
      <pubDate>Tue, 03 Mar 2009 09:41:42 GMT</pubDate>
      <description>&lt;p&gt;
I talked about the new &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx"&gt;WF4
Runtime model&lt;/a&gt; a while back. One of the things I discussed was the new data flow
model of arguments and variables. However, if you are used to WF 3.5 something looks
a bit odd here. Lets look at a simple activity example:
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-size: 11px; color: black; font-family: courier new; background-color: transparent"&gt;&lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;public&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;class&lt;/span&gt; WriteLineActivity
: WorkflowElement&lt;br&gt;
{&lt;br&gt;
&lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
public&lt;/span&gt; &lt;strong&gt;InArgument&amp;lt;&lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;string&lt;/span&gt;&amp;gt;
Text&lt;/strong&gt; { get; set; }&lt;br&gt;
&lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
protected&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;override&lt;/span&gt; &lt;span style="font-size: 11px; color: blue; font-family: courier new; background-color: transparent"&gt;void&lt;/span&gt; Execute(ActivityExecutionContext
context)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;strong&gt;Text.Get(context)&lt;/strong&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-size: 11px; color: black; font-family: courier new; background-color: transparent"&gt;&lt;font face="Trebuchet MS" size="2"&gt;Why
do I need to pass the ActivityExecutionContext when I want to get the data from the
argument? This highlights a subtlety to the change in the runtime model. The activity
is really just a template. A class called ActivityInstance is the thing that is actually
executed, it just has a reference to the actual activity to be able to hand off to
the activty’s methods (e.g. Execute). The actual argument state is stored in a construct
called the LocalEnvironment. The ActivityExecutionContext gives access to&amp;nbsp; the
current ActivityInstance and that in turn holds a reference to the current LocalEnvironment.
Therefore, to get from&amp;nbsp; an activity’s Execute method to its state we have to
go via the ActivityExecutionContext.&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=5a7759a2-c6c3-41f6-af58-ba4f82becc9a" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=d32be8a7-aa1b-4d2f-9e54-780cf57528a4</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,d32be8a7-aa1b-4d2f-9e54-780cf57528a4.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve been writing a lab on Workflow Services in 4.0 recently. Part of what I was showing
was the new data orientated correlation (the same kind of mechanism that BizTalk uses
for correlation). So I wanted to have two operations that were correlated to the same
workflow instance based on data in the message (rather than a smuggled context id
as 3.5 does it). As I was writing this lab I suddenly started getting an <font face="Courier New">InvalidOperationException</font> stating <strong><em>DispatchOperation
requires Invoker</em></strong> every time I brought the .xamlx file up in a browser.
It appeared that others had seen this as well but not really solved it. So I dug around
looking at the XAML (workflow services can be written fully declaratively now) and
the config file and could see no issues there. I asked around but no one I asked knew
the reason. 
</p>
        <p>
So I created a simple default Declarative Workflow Service project and that worked
ok. I compared my lab workflow and the default one and it suddenly dawned on me what
was wrong. The default project has just one operation on the contract and has a ServiceOperationActivity
to implement it. My contract had my two operations but I had, so far, only bound one
ServiceOperationActivity. So in other words I had not implemented the contract. This
is obviously an issue and looking back I’m annoyed I didn’t see it sooner.
</p>
        <p>
However, the problem is that this is a change in behavior between 3.5 and 4.0. In
3.5 if I didn’t bind a ReceiveActivity to every operation I got a validation warning
but I could still retrieve metadata; in 4.0 you get a fatal error. Its not hugely
surprising that the behavior has changed – after all the whole infrastructure has
been rewritten.
</p>
        <p>
On the whole its a good thing that implementation of the contract is enforced – although
it would be nice if the validation infrastructure caught this at compile time rather
than it being a runtime failure.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=d32be8a7-aa1b-4d2f-9e54-780cf57528a4" />
      </body>
      <title>Workflow 4.0 Services and &amp;ldquo;InvalidOperationException: DispatchOperation requires Invoker&amp;rdquo;</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,d32be8a7-aa1b-4d2f-9e54-780cf57528a4.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,d32be8a7-aa1b-4d2f-9e54-780cf57528a4.aspx</link>
      <pubDate>Thu, 22 Jan 2009 10:10:15 GMT</pubDate>
      <description>&lt;p&gt;
I’ve been writing a lab on Workflow Services in 4.0 recently. Part of what I was showing
was the new data orientated correlation (the same kind of mechanism that BizTalk uses
for correlation). So I wanted to have two operations that were correlated to the same
workflow instance based on data in the message (rather than a smuggled context id
as 3.5 does it). As I was writing this lab I suddenly started getting an &lt;font face="Courier New"&gt;InvalidOperationException&lt;/font&gt; stating &lt;strong&gt;&lt;em&gt;DispatchOperation
requires Invoker&lt;/em&gt;&lt;/strong&gt; every time I brought the .xamlx file up in a browser.
It appeared that others had seen this as well but not really solved it. So I dug around
looking at the XAML (workflow services can be written fully declaratively now) and
the config file and could see no issues there. I asked around but no one I asked knew
the reason. 
&lt;/p&gt;
&lt;p&gt;
So I created a simple default Declarative Workflow Service project and that worked
ok. I compared my lab workflow and the default one and it suddenly dawned on me what
was wrong. The default project has just one operation on the contract and has a ServiceOperationActivity
to implement it. My contract had my two operations but I had, so far, only bound one
ServiceOperationActivity. So in other words I had not implemented the contract. This
is obviously an issue and looking back I’m annoyed I didn’t see it sooner.
&lt;/p&gt;
&lt;p&gt;
However, the problem is that this is a change in behavior between 3.5 and 4.0. In
3.5 if I didn’t bind a ReceiveActivity to every operation I got a validation warning
but I could still retrieve metadata; in 4.0 you get a fatal error. Its not hugely
surprising that the behavior has changed – after all the whole infrastructure has
been rewritten.
&lt;/p&gt;
&lt;p&gt;
On the whole its a good thing that implementation of the contract is enforced – although
it would be nice if the validation infrastructure caught this at compile time rather
than it being a runtime failure.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=d32be8a7-aa1b-4d2f-9e54-780cf57528a4" /&gt;</description>
      <category>.NET;BizTalk;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ce83b5da-61ed-4b63-b523-f2ec2c0fdbc2</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ce83b5da-61ed-4b63-b523-f2ec2c0fdbc2.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm really excited to announce that I've joined <a href="http://www.thinktecture.com/">thinktecture</a> as
a consultant. I've known <a href="http://blogs.thinktecture.com/ingo/">Ingo</a>, <a href="http://blogs.thinktecture.com/cweyer/">Christian</a> and <a href="http://www.leastprivilege.com/">Dominick</a> for
some time now and its great to take that relationship on to a new level. I have huge
respect for the abilities of the thinktecture team and so it was fantastic when they
asked me if I was interested in working with them. 
</p>
        <p>
I'll be focusing on all things distributed at thinktecture - so that includes WCF,
Workflow, BizTalk, Dublin and Azure. And I guess I'll have to learn to speak
German now ...
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ce83b5da-61ed-4b63-b523-f2ec2c0fdbc2" />
      </body>
      <title>New colleagues, old friends</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ce83b5da-61ed-4b63-b523-f2ec2c0fdbc2.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ce83b5da-61ed-4b63-b523-f2ec2c0fdbc2.aspx</link>
      <pubDate>Sat, 10 Jan 2009 18:27:22 GMT</pubDate>
      <description>&lt;p&gt;
I'm really excited to announce that I've joined &lt;a href="http://www.thinktecture.com/"&gt;thinktecture&lt;/a&gt; as
a consultant. I've&amp;nbsp;known &lt;a href="http://blogs.thinktecture.com/ingo/"&gt;Ingo&lt;/a&gt;, &lt;a href="http://blogs.thinktecture.com/cweyer/"&gt;Christian&lt;/a&gt; and &lt;a href="http://www.leastprivilege.com/"&gt;Dominick&lt;/a&gt; for
some time now and its great to take that relationship on to a new level. I have huge
respect for the abilities of the thinktecture team and so it was fantastic when they
asked me if I was interested in working with them. 
&lt;/p&gt;
&lt;p&gt;
I'll be focusing on all things distributed at thinktecture - so that includes WCF,
Workflow, BizTalk,&amp;nbsp;Dublin&amp;nbsp;and Azure. And I guess I'll have to learn to speak
German now ...
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ce83b5da-61ed-4b63-b523-f2ec2c0fdbc2" /&gt;</description>
      <category>Azure;BizTalk;Dublin;Life;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=9e79390b-cf28-43fb-88f4-a0dfa1e2895b</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9e79390b-cf28-43fb-88f4-a0dfa1e2895b.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As I said in my <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx">previous
post</a>, asynchrony and persistence enable arguable the most powerful feature of
workflow, that of stateful, long running execution. However as I also said, the WF
runtime has been rewritten for WF 4.0 - so what does asynchrony and persistence look
like in the 4.0 release?
</p>
        <p>
First lets look at what was problematic in WF 3.5 in this area:
</p>
        <ul>
          <li>
Writing an asynchronous activity was <a href="http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx">hellishly
complex</a> as they get executed differently dependent on their parent (State Machine,
Listen Activity, standard activity) 
</li>
          <li>
There was no model for performing async work that didn't open up the possibility of
being persisted during processing. This is fine if you are waiting for a nightly extract
file to arrive on a share; its a real problem if you are trying to invoke a service
asynchronously as the workflow may have been unloaded by the time the HTTP response
comes back</li>
        </ul>
        <p>
The WF team have tried to solve both of these problems in this release and in addition
obviously have to align with the new runtime model I talked about in my <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx">last
post</a>. Lets talk about async first and then we'll look at the related but separate
issue of persistence.
</p>
        <p>
The standard asynchronous model has been streamlined so the communication mechanisms
have been wrapped in the concept of a <em>Bookmark</em>. A bookmark represents a resumable
point of execution. Lets look at the code for an async activity using bookmarks.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> StandardAsyncActivity
: WorkflowElement<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Execute(ActivityExecutionContext
context)<br />
    {<br />
        BookmarkCallback cb <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Callback;<br />
        context.CreateNamedBookmark(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"rlBookMark"</span>,
cb, BookmarkOptions.MultipleResume);<br />
    }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
int</span> callTimes <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Callback(ActivityExecutionContext
ctx, Bookmark bm, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> state)<br />
    {<br />
        callTimes++;<br />
        Console.WriteLine(state);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">       
if</span> (callTimes == 2)<br />
        {<br />
            bm.Close(ctx);<br />
        }<br /><br />
    }<br />
}</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">This
code demonstrates a number of features. In 3.5 an activity indicated it was async
by returning <font face="Courier New">ActivityExecutionStatus.Executing</font> from
the <font face="Courier New">Execute</font> method. However, here the workflow runtime
knows that this activity has yet to complete as it has an outstanding bookmark. When
the activity is done with bookmark processing (in this case it receives two pieces
of data) it simply closes it and since the runtime now knows it has no outstanding
bookmarks the activity must be complete. Also notice that no special interfaces require
implementation, the activity simply associates a callback to be fired when execution
resumes at this bookmark. </font>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">So
how does execution resume? Heres the code:</font>
          </span>
        </p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">myInstance.ResumeBookmark(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"rlBookMark"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"hello
bookmark"</span>);<br /></span>
          </p>
          <p>
            <font face="Verdana" size="2">This code is in the host or an extension (new name for
a workflow runtime service) associated with the activity and as you can see is very
simple. </font>
          </p>
          <p>
            <font face="Verdana" size="2">With this model, after <font face="Courier New">Execute</font> returns
and after each bookmark callback that doesn't close the bookmark, the workflow will
go idle (assuming no other activities are runnable) and could be unloaded and/or persisted.
So this is ideal for situations where the next execution resumption will be after
some time. However, if we're simply performing async IO then the next resumption may
be subsecond. </font>
          </p>
          <p>
            <font face="Verdana" size="2">This model will not work for such processing and so
there is a lightweight version of async processing in 4.0. Lets look at an example</font>
          </p>
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> LightweightAsyncActivity
: WorkflowElement<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Execute(ActivityExecutionContext
context)<br />
    {<br />
        AsyncOperationContext block <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> context.SetupAsyncOperationBlock();<br /><br />
        Action a <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> AsyncWork;<br /><br />
        AsyncCallback cb <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span>(IAsyncResult
iar)<br />
        {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">           
// called on non workflow thread</span><br />
            a.EndInvoke(iar);<br />
            block.BeginCompleteOperation(AsyncProcessingComplete, <br />
                                         <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>, 
<br />
                                        
ar =&gt; block.EndCompleteOperation(ar), 
<br />
                                         <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>);<br />
        };<br /><br />
        a.BeginInvoke(cb, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>);<br />
    } 
<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AsyncProcessingComplete(ActivityExecutionContext
ctx, Bookmark bm, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> val)<br />
    {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">       
// called on workflow thread</span><br />
        Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Bookmark
callback"</span>);<br />
    }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AsyncWork()<br />
    {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">       
// called on non workflow thread</span><br />
        Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Sleeping"</span>);<br />
        Thread.Sleep(2000);<br />
        Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Done
Sleeping"</span>);<br />
    }<br />
}<br /></span>
          </p>
          <p>
            <font face="Verdana" size="2">This time, instead of explicitly creating a bookmark
we create an <font face="Courier New">AsyncOperationContext</font>. This then allows
us to run on a separate thread (<font face="Courier New">BeginInvoke</font> hands
the <font face="Courier New">AsyncWork</font> method to the threadpool) and then when
it completes tell the workflow infrastructure that our async work is done. It also
allows us to provide another method that will execute on a workflow thread in case
there are other workflow related tasks we need to perform (<font face="Courier New">AsyncProcessingComplete</font> in
the above example). Although when <em>Execute</em> returns the workflow will go idle,
this infrastructure puts in place a new construct called a <em>No Persist Block</em> that
prevents persistence while the async operation is in progress.</font>
          </p>
          <p>
            <font face="Verdana" size="2">So these are the two new async models but how does the
new persistence model interact. Well the above description mentions some interaction
but lets look at 4.0 persistence in more detail and then draw the two parts of the
post together.</font>
          </p>
          <p>
            <font face="Verdana" size="2">The <font face="Courier New">WorkflowPersistenceService</font> has
now been remodelled in terms of <em>Persistence Providers</em>. You get one out-of-the-box
as before for SQL Server. There are two scripts to run against a database to put the
new persistence constructs in place <font face="Courier New">SqlPersistenceProviderSchema40.sql</font> and <font face="Courier New">SqlPersistenceProviderLogic40.sql</font></font>.<font face="Verdana" size="2">To
enable the sql persistence provider you create an instance of the provider for each
workflow instance using a factory and add it as an extension to that workflow instance:</font></p>
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> conn <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"server=.;database=WFPersist;integrated
security=SSPI"</span>;<br />
SqlPersistenceProviderFactory fact <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> SqlPersistenceProviderFactory(conn, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);<br />
fact.Open();<br /><br />
WorkflowInstance myInstance <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> WorkflowInstance.Create(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWorkflow());<br /><br />
PersistenceProvider pp <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fact.CreateProvider(myInstance.Id);<br />
myInstance.Extensions.Add(pp);<br /><br />
pp.Open();<br /></span>
          </p>
          <p>
            <font face="Verdana" size="2">The factory and the provider must be have <font face="Courier New">Open</font> called
on them as they both derive from the WCF <font face="Courier New">CommunicationObject</font> class
(presumably due to the way this layers in for durable services and Dublin). Note that
there is no flag for the provider equivelent to 3.5's <font face="Courier New">PersistOnIdle</font>.
It is now up to the host to specifically call <font face="Courier New">Persist</font> or <font face="Courier New">Unload</font> on
the <font face="Courier New">WorkflowInstance</font> if wants it persisted or unloaded.
So now in the <font face="Courier New">Idle</font> event you may put code like this:</font>
          </p>
        </span>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">myInstance.Idle
+= <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span><br />
{<br />
    myInstance.TryPersist(TimeSpan.FromSeconds(5));<br />
};</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">I'll
come back to why use <font face="Courier New">TryPersist</font> rather than <font face="Courier New">Persist</font> in
a moment. However, there is another job to be done. You need to explicitly tell the
persistence provider that you are done with a workflow instance to ensure that it
gets deleted from the persistence store when the workflow completes. And so you will
typically call <font face="Courier New">Unload</font> in the <font face="Courier New">Completed</font> event:</font>
          </span>
        </p>
        <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
          <font face="Verdana" size="2">
            <p>
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">myInstance.Completed
+= <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span>(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
WorkflowCompletedEventArgs e) 
<br />
{<br />
    myInstance.TryUnload(TimeSpan.FromSeconds(5));<br />
};<br /></span>
            </p>
          </font>
        </span>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">However,
things are a little gnarly here. Remember above that both the <font face="Courier New">Bookmark</font> and <font face="Courier New">AsyncOperationBlock</font> models
for async will trigger the <font face="Courier New">Idle</font> event but the <font face="Courier New">AsyncOperationBlock</font> prevents
persistence. Thats why we have to use <font face="Courier New">TryPersist</font> and <font face="Courier New">TryUnload</font> as <font face="Courier New">Persist</font> and <font face="Courier New">Unload</font> will
throw exceptions if persistence is not possible. The team have said they are working
on getting this revised for beta 1 and having seen a preview of the kind of things
they are looking at it should be a lot neater then.</font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">So
thats the new async and persistence model for WF 4.0. The simplicity and extra functionality
now in the async model will take away a good deal of the complexity in building custom
activtities that play well in the long running workflow infrastructure</font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">
            </font>
          </span> 
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" size="2">
            </font> 
</span>
        </p>
        <p>
          <br />
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=9e79390b-cf28-43fb-88f4-a0dfa1e2895b" />
      </body>
      <title>WF 4.0: Asynchrony and Persistence</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9e79390b-cf28-43fb-88f4-a0dfa1e2895b.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9e79390b-cf28-43fb-88f4-a0dfa1e2895b.aspx</link>
      <pubDate>Wed, 10 Dec 2008 14:32:56 GMT</pubDate>
      <description>&lt;p&gt;
As I said in my &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx"&gt;previous
post&lt;/a&gt;, asynchrony and persistence enable arguable the most powerful feature of
workflow, that of stateful, long running execution. However as I also said, the WF
runtime has been rewritten for WF 4.0 - so what does asynchrony and persistence look
like in the 4.0 release?
&lt;/p&gt;
&lt;p&gt;
First lets look at what was problematic in WF 3.5 in this area:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Writing an asynchronous activity was &lt;a href="http://www.dotnetconsult.co.uk/weblog2/CommentView,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx"&gt;hellishly
complex&lt;/a&gt; as they get executed differently dependent on their parent (State Machine,
Listen Activity, standard activity) 
&lt;li&gt;
There was no model for performing async work that didn't open up the possibility of
being persisted during processing. This is fine if you are waiting for a nightly extract
file to arrive on a share; its a real problem if you are trying to invoke a service
asynchronously as the workflow may have been unloaded by the time the HTTP response
comes back&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The WF team have tried to solve both of these problems in this release and in addition
obviously have to align with the new runtime model I talked about in my &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx"&gt;last
post&lt;/a&gt;. Lets talk about async first and then we'll look at the related but separate
issue of persistence.
&lt;/p&gt;
&lt;p&gt;
The standard asynchronous model has been streamlined so the communication mechanisms
have been wrapped in the concept of a &lt;em&gt;Bookmark&lt;/em&gt;. A bookmark represents a resumable
point of execution. Lets look at the code for an async activity using bookmarks.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; StandardAsyncActivity
: WorkflowElement&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Execute(ActivityExecutionContext
context)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BookmarkCallback cb &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Callback;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; context.CreateNamedBookmark(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"rlBookMark"&lt;/span&gt;,
cb, BookmarkOptions.MultipleResume);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
int&lt;/span&gt; callTimes &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Callback(ActivityExecutionContext
ctx, Bookmark bm, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; state)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; callTimes++;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(state);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (callTimes == 2)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bm.Close(ctx);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;This
code demonstrates a number of features. In 3.5 an activity indicated it was async
by returning &lt;font face="Courier New"&gt;ActivityExecutionStatus.Executing&lt;/font&gt; from
the &lt;font face="Courier New"&gt;Execute&lt;/font&gt; method. However, here the workflow runtime
knows that this activity has yet to complete as it has an outstanding bookmark. When
the activity is done with bookmark processing (in this case it receives two pieces
of data) it simply closes it and since the runtime now knows it has no outstanding
bookmarks the activity must be complete. Also notice that no special interfaces require
implementation, the activity simply associates a callback to be&amp;nbsp;fired when execution
resumes at this bookmark. &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;So
how does execution resume? Heres the code:&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;myInstance.ResumeBookmark(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"rlBookMark"&lt;/span&gt;, &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"hello
bookmark"&lt;/span&gt;);&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;This code is in the host or an extension (new name for a
workflow runtime service) associated with the activity and as you can see is very
simple. &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;With this model, after &lt;font face="Courier New"&gt;Execute&lt;/font&gt; returns
and after each bookmark callback that doesn't close the bookmark, the workflow will
go idle (assuming no other activities are runnable) and could be unloaded and/or persisted.
So this is ideal for situations where the next execution resumption will be after
some time. However, if we're simply performing async IO then the next resumption may
be subsecond. &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;This model will not work for such processing and so there
is a lightweight version of async processing in 4.0. Lets look at an example&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; LightweightAsyncActivity
: WorkflowElement&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Execute(ActivityExecutionContext
context)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AsyncOperationContext block &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; context.SetupAsyncOperationBlock();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Action a &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; AsyncWork;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AsyncCallback cb &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt;(IAsyncResult
iar)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// called on non workflow thread&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a.EndInvoke(iar);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;block.BeginCompleteOperation(AsyncProcessingComplete,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
ar =&amp;gt; block.EndCompleteOperation(ar), 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; a.BeginInvoke(cb, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AsyncProcessingComplete(ActivityExecutionContext
ctx, Bookmark bm, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; val)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// called on workflow thread&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Bookmark
callback"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AsyncWork()&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// called on non workflow thread&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Sleeping"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.Sleep(2000);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Done
Sleeping"&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;This time, instead of explicitly creating a bookmark we
create an &lt;font face="Courier New"&gt;AsyncOperationContext&lt;/font&gt;. This then allows
us to run on a separate thread (&lt;font face="Courier New"&gt;BeginInvoke&lt;/font&gt; hands
the &lt;font face="Courier New"&gt;AsyncWork&lt;/font&gt; method to the threadpool) and then when
it completes tell the workflow infrastructure that our async work is done. It also
allows us to provide another method that will execute on a workflow thread in case
there are other workflow related tasks we need to perform (&lt;font face="Courier New"&gt;AsyncProcessingComplete&lt;/font&gt; in
the above example). Although when &lt;em&gt;Execute&lt;/em&gt; returns the workflow will go idle,
this infrastructure puts in place a new construct called a &lt;em&gt;No Persist Block&lt;/em&gt; that
prevents persistence while the async operation is in progress.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;So these are the two new async models but how does the new
persistence model interact. Well the above description mentions some interaction but
lets look at 4.0 persistence in more detail and then draw the two parts of the post
together.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;The &lt;font face="Courier New"&gt;WorkflowPersistenceService&lt;/font&gt; has
now been remodelled in terms of &lt;em&gt;Persistence Providers&lt;/em&gt;. You get one out-of-the-box
as before for SQL Server. There are two scripts to run against a database to put the
new persistence constructs in place &lt;font face="Courier New"&gt;SqlPersistenceProviderSchema40.sql&lt;/font&gt; and &lt;font face="Courier New"&gt;SqlPersistenceProviderLogic40.sql&lt;/font&gt;&lt;/font&gt;.&lt;font face=Verdana size=2&gt;To
enable the sql persistence provider you create an instance of the provider for each
workflow instance using a factory and add it as an extension to that workflow instance:&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; conn &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"server=.;database=WFPersist;integrated
security=SSPI"&lt;/span&gt;;&lt;br&gt;
SqlPersistenceProviderFactory fact &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; SqlPersistenceProviderFactory(conn, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;true&lt;/span&gt;);&lt;br&gt;
fact.Open();&lt;br&gt;
&lt;br&gt;
WorkflowInstance myInstance &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; WorkflowInstance.Create(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWorkflow());&lt;br&gt;
&lt;br&gt;
PersistenceProvider pp &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fact.CreateProvider(myInstance.Id);&lt;br&gt;
myInstance.Extensions.Add(pp);&lt;br&gt;
&lt;br&gt;
pp.Open();&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;The factory and the provider must be have &lt;font face="Courier New"&gt;Open&lt;/font&gt; called
on them as they both derive from the WCF &lt;font face="Courier New"&gt;CommunicationObject&lt;/font&gt; class
(presumably due to the way this layers in for durable services and Dublin). Note that
there is no flag for the provider equivelent to 3.5's &lt;font face="Courier New"&gt;PersistOnIdle&lt;/font&gt;.
It is now up to the host to specifically call &lt;font face="Courier New"&gt;Persist&lt;/font&gt; or &lt;font face="Courier New"&gt;Unload&lt;/font&gt; on
the &lt;font face="Courier New"&gt;WorkflowInstance&lt;/font&gt; if wants it persisted or unloaded.
So now in the &lt;font face="Courier New"&gt;Idle&lt;/font&gt; event you may put code like this:&lt;/font&gt;
&lt;/p&gt;
&lt;/span&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;myInstance.Idle
+= &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt;
&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; myInstance.TryPersist(TimeSpan.FromSeconds(5));&lt;br&gt;
};&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;I'll
come back to why use &lt;font face="Courier New"&gt;TryPersist&lt;/font&gt; rather than &lt;font face="Courier New"&gt;Persist&lt;/font&gt; in
a moment. However, there is another job to be done. You need to explicitly tell the
persistence provider that you are done with a workflow instance to ensure that it
gets deleted from the persistence store when the workflow completes. And so you will
typically call &lt;font face="Courier New"&gt;Unload&lt;/font&gt; in the &lt;font face="Courier New"&gt;Completed&lt;/font&gt; event:&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;myInstance.Completed
+= &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
WorkflowCompletedEventArgs e) 
&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; myInstance.TryUnload(TimeSpan.FromSeconds(5));&lt;br&gt;
};&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;However,
things are a little gnarly here. Remember above that both the &lt;font face="Courier New"&gt;Bookmark&lt;/font&gt; and &lt;font face="Courier New"&gt;AsyncOperationBlock&lt;/font&gt; models
for async will trigger the &lt;font face="Courier New"&gt;Idle&lt;/font&gt; event but the &lt;font face="Courier New"&gt;AsyncOperationBlock&lt;/font&gt; prevents
persistence. Thats why we have to use &lt;font face="Courier New"&gt;TryPersist&lt;/font&gt; and &lt;font face="Courier New"&gt;TryUnload&lt;/font&gt; as &lt;font face="Courier New"&gt;Persist&lt;/font&gt; and &lt;font face="Courier New"&gt;Unload&lt;/font&gt; will
throw exceptions if persistence is not possible. The team have said they are working
on getting this revised for beta 1 and having seen a preview of the kind of things
they are looking at it should be a lot neater then.&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;So
thats the new async and persistence model for WF 4.0. The simplicity and extra functionality
now in the async model will take away a good deal of the complexity in building custom
activtities that play well in the long running workflow infrastructure&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;&lt;/font&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana size=2&gt;&lt;/font&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=9e79390b-cf28-43fb-88f4-a0dfa1e2895b" /&gt;</description>
      <category>.NET;Dublin;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=707e4cb9-6111-4069-96b3-596e87f2e262</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've always found the workflow execution model very compelling. Its a very different
way of thinking about writing applications but it solves a set of difficult problems particularly
in the area of asynchronous and long-running processing. So when I found out
that .NET 4.0 introduces a new version of the workflow infrastructure I was intregued
as to what changes had been made.
</p>
        <p>
The ideas behind workflow have not changed but the WF 4.0 implementation is very different
from the 3.5 one, involving a very different API and a rewritten design-time experience.
The decision to do a ground up rewrite was not taken lightly and was necessary to
resolve issues that people were facing with 3.5 - particularly around serialization,
performance and complexity. So you can say goodbye to <font face="Courier New">WorkflowRuntime</font>, <font face="Courier New">WorkflowRuntimeService</font>, <font face="Courier New">WorkflowQueue</font>, <font face="Courier New">ActivityExecutionStatus</font>, <font face="Courier New">IEventActivity</font> and
a number of other familiar classes and interfaces; the new API looks quite different.
</p>
        <p>
So lets look at the code to create and execute a workflow in WF 4.0
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WorkflowInstance
myInstance <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> WorkflowInstance.Create(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWorkflow());<br /><br />
myInstance.Resume();<br /><br />
Console.WriteLine(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Press
enter to exit"</span>);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> data <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Console.ReadLine();</span>
        </p>
        <p>
So firstly two things are the same: you still use a <font face="Courier New">WorkflowInstance </font>object
to address the workflow and starting the workflow is still an asychronous operation.
However, notice that we don't use <font face="Courier New">WorkflowRuntime</font> to
create the workflow, everything is done against the WorkflowInstance itself.
</p>
        <p>
There is also a more lightweight workflow execution model if you simply want to inline
some workflow functionality
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">WorkflowInvoker
inv <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> WorkflowInvoker(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> MyWorkflow());<br />
inv.Invoke();<br /></span>
        </p>
        <p>
Workflows are now, by default, authored declaratively in XAML as are custom activities.
In fact the activtity model looks quite different. The base unity of execution in
a workflow is a <font face="Courier New">WorkflowElement</font>. Activities are composite
activities, normally declared in XAML and these ultimately derive from <font face="Courier New">WorkflowElement</font>.
However, neither of these constructs is actually executed; an <font face="Courier New">ActivityInstance</font> is
generated from the activity definition and it is this that is executed. This is because
arbitrary state can be attached to an executing activity in the form of <em>variables</em>.
An activity can only bind its own state (modelled explicitly in the form of <em>arguments</em>)
to variables declared on its parent or other ancestors. This is a very different model
from 3.5 where an activity's state could be data bound to properties of any other
activity in the entire workflow activity tree. This mean't, in effect, that to truly
capture the state of a workflow you can to serialize the entire activity tree, including
those activties that had finished execution and those that had yet to start execution.
We can see this here
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/35Persistence.jpg" border="0" />
        </p>
        <p>
The 4.0 model only requires the currently executing set of activities to be serialized
as they cannot bind state outside of their parental relationships
</p>
        <p>
 
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/40Persistence.jpg" border="0" />
        </p>
        <p>
This makes persistence much faster and more compact.
</p>
        <p>
Creating custom activties is often a case of combining building blocks defined as
other activties - these are generally modelled in XAML. However, what if you want
to create a building block activity yourself? In this case you simply derive from <font face="Courier New">WorkflowElement</font> directly
and override the <font face="Courier New">Execute</font> method. This sounds a lot
like creating custom activities in 3.5, however there are important differences. Firstly
state in and out of an activity is explicitly modelled with arguments that have direction,
secondly you no longer have to tell the runtime when the activity is finished or not
in <font face="Courier New">Execute</font> - the runtime knows based on what actions
you perform.
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> WriteLineActivity
: WorkflowElement<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
public</span> InArgument&lt;<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>&gt;
Text { get; set; }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
protected</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">override</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Execute(ActivityExecutionContext
context)<br />
    {<br />
        Console.WriteLine(Text.Get(context));<br />
    }<br />
}<br /></span>
        </p>
        <p>
Notice here that this activity is assuming that it is running in a Console host. Generally
we try to avoid tying an activity to a certain type of host and this was achieved
in 3.5 by using pluggable Workflow Runtime Services. The same is true in 4.0 but these
services have been renamed <em>Extensions</em> to avoid confusion with Workflow Services
(where workflow is used to implement a WCF service). The <font face="Courier New">WorkflowInstance</font> class
now has an <font face="Courier New">Extensions</font> collection and the <font face="Courier New">ActivityExecutionContext</font> has
a <font face="Courier New">GetExtension&lt;T&gt;</font> method for the activity to
retrieve an extension it is interested in.
</p>
        <p>
Some of the real power of the workflow infrastructure only becomes apparent when you
plug in a persistence service and your activties are asynchronous so the workflow
can be taken out of memory. It is this combination that allows workflows to perform
long running processing and this infrastructure has also changed a great deal. However I
will walk through those changes in my <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9e79390b-cf28-43fb-88f4-a0dfa1e2895b.aspx">next
post</a>.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=707e4cb9-6111-4069-96b3-596e87f2e262" />
      </body>
      <title>WF 4.0 - the new runtime model</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,707e4cb9-6111-4069-96b3-596e87f2e262.aspx</link>
      <pubDate>Wed, 10 Dec 2008 10:44:27 GMT</pubDate>
      <description>&lt;p&gt;
I've always found the workflow execution model very compelling. Its a very different
way of thinking about writing applications but it solves a set of&amp;nbsp;difficult problems&amp;nbsp;particularly
in the area of&amp;nbsp;asynchronous and long-running processing. So when I found out
that .NET 4.0 introduces a new version of the workflow infrastructure I was intregued
as to what changes had been made.
&lt;/p&gt;
&lt;p&gt;
The ideas behind workflow have not changed but the WF 4.0 implementation is very different
from the 3.5 one, involving a very different API and a rewritten design-time experience.
The decision to do a ground up rewrite was not taken lightly and was necessary to
resolve issues that people were facing with 3.5 - particularly around serialization,
performance and complexity. So you can say goodbye to &lt;font face="Courier New"&gt;WorkflowRuntime&lt;/font&gt;, &lt;font face="Courier New"&gt;WorkflowRuntimeService&lt;/font&gt;, &lt;font face="Courier New"&gt;WorkflowQueue&lt;/font&gt;, &lt;font face="Courier New"&gt;ActivityExecutionStatus&lt;/font&gt;,&amp;nbsp;&lt;font face="Courier New"&gt;IEventActivity&lt;/font&gt;&amp;nbsp;and
a number of other familiar classes and interfaces; the new API looks quite different.
&lt;/p&gt;
&lt;p&gt;
So lets look at the code to create and execute a workflow in WF 4.0
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WorkflowInstance
myInstance &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; WorkflowInstance.Create(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWorkflow());&lt;br&gt;
&lt;br&gt;
myInstance.Resume();&lt;br&gt;
&lt;br&gt;
Console.WriteLine(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Press
enter to exit"&lt;/span&gt;);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; data &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Console.ReadLine();&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
So firstly two things are the same: you still use a &lt;font face="Courier New"&gt;WorkflowInstance &lt;/font&gt;object
to address the workflow and starting the workflow is still an asychronous operation.
However, notice that we don't use &lt;font face="Courier New"&gt;WorkflowRuntime&lt;/font&gt; to
create the workflow, everything is done against the WorkflowInstance itself.
&lt;/p&gt;
&lt;p&gt;
There is also a more lightweight workflow execution model if you simply want to inline
some workflow functionality
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;WorkflowInvoker
inv &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; WorkflowInvoker(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; MyWorkflow());&lt;br&gt;
inv.Invoke();&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Workflows are now, by default, authored declaratively in XAML as are custom activities.
In fact the activtity model looks quite different. The base unity of execution in
a workflow is a &lt;font face="Courier New"&gt;WorkflowElement&lt;/font&gt;. Activities are composite
activities, normally declared in XAML and these ultimately derive from &lt;font face="Courier New"&gt;WorkflowElement&lt;/font&gt;.
However, neither of these constructs is actually executed; an &lt;font face="Courier New"&gt;ActivityInstance&lt;/font&gt; is
generated from the activity definition and it is this that is executed. This is because
arbitrary state can be attached to an executing activity in the form of &lt;em&gt;variables&lt;/em&gt;.
An activity can only bind its own state (modelled explicitly in the form of &lt;em&gt;arguments&lt;/em&gt;)
to variables declared on its parent or other ancestors. This is a very different model
from 3.5 where an activity's state could be data bound to properties of any other
activity in the entire workflow activity tree. This mean't, in effect, that to truly
capture the state of a workflow you can to serialize the entire activity tree, including
those activties that had finished execution and those that had yet to start execution.
We can see this here
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/35Persistence.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The 4.0 model only requires the currently executing set of activities to be serialized
as they cannot bind state outside of their parental relationships
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/40Persistence.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
This makes persistence much faster and more compact.
&lt;/p&gt;
&lt;p&gt;
Creating custom activties is often a case of combining building blocks defined as
other activties - these are generally modelled in XAML. However, what if you want
to create a building block activity yourself? In this case you simply derive from &lt;font face="Courier New"&gt;WorkflowElement&lt;/font&gt; directly
and override the &lt;font face="Courier New"&gt;Execute&lt;/font&gt; method. This sounds a lot
like creating custom activities in 3.5, however there are important differences. Firstly
state in and out of an activity is explicitly modelled with arguments that have direction,
secondly you no longer have to tell the runtime when the activity is finished or not
in &lt;font face="Courier New"&gt;Execute&lt;/font&gt; - the runtime knows based on what actions
you perform.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; WriteLineActivity
: WorkflowElement&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
public&lt;/span&gt; InArgument&amp;lt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;&amp;gt;
Text { get; set; }&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
protected&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;override&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; Execute(ActivityExecutionContext
context)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(Text.Get(context));&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
Notice here that this activity is assuming that it is running in a Console host. Generally
we try to avoid tying an activity to a certain type of host and this was achieved
in 3.5 by using pluggable Workflow Runtime Services. The same is true in 4.0 but these
services have been renamed &lt;em&gt;Extensions&lt;/em&gt; to avoid confusion with Workflow Services
(where workflow is used to implement a WCF service). The &lt;font face="Courier New"&gt;WorkflowInstance&lt;/font&gt; class
now has an &lt;font face="Courier New"&gt;Extensions&lt;/font&gt; collection and the &lt;font face="Courier New"&gt;ActivityExecutionContext&lt;/font&gt; has
a &lt;font face="Courier New"&gt;GetExtension&amp;lt;T&amp;gt;&lt;/font&gt; method for the activity to
retrieve an extension it is interested in.
&lt;/p&gt;
&lt;p&gt;
Some of the real power of the workflow infrastructure only becomes apparent when you
plug in a persistence service and your activties are asynchronous so the workflow
can be taken out of memory. It is this combination that allows workflows to perform
long running processing and this infrastructure has also changed a great deal. However&amp;nbsp;I
will walk through those changes in my &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9e79390b-cf28-43fb-88f4-a0dfa1e2895b.aspx"&gt;next
post&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=707e4cb9-6111-4069-96b3-596e87f2e262" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=3a23fff1-fce3-41d9-8e3f-d6a298d3c8ac</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,3a23fff1-fce3-41d9-8e3f-d6a298d3c8ac.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.develop.com/uk">DevelopMentor UK</a> ran a one day post PDC event
on Friday at the Microsoft Offices in London. Myself and <a href="http://www.leastprivilege.com/">Dominick</a> covered
WF 4.0, Dublin, Geneva, Azure and Oslo
</p>
        <p>
You can find the materials and demos <a href="http://staff.develop.com/richardb/PostPDCDownload.zip">here</a></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=3a23fff1-fce3-41d9-8e3f-d6a298d3c8ac" />
      </body>
      <title>Post PDC Event Slides and Materials</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,3a23fff1-fce3-41d9-8e3f-d6a298d3c8ac.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,3a23fff1-fce3-41d9-8e3f-d6a298d3c8ac.aspx</link>
      <pubDate>Mon, 01 Dec 2008 11:30:39 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.develop.com/uk"&gt;DevelopMentor UK&lt;/a&gt; ran a one day post PDC event
on Friday at the Microsoft Offices in London. Myself and &lt;a href="http://www.leastprivilege.com/"&gt;Dominick&lt;/a&gt; covered
WF 4.0, Dublin, Geneva, Azure and Oslo
&lt;/p&gt;
&lt;p&gt;
You can find the materials and demos &lt;a href="http://staff.develop.com/richardb/PostPDCDownload.zip"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=3a23fff1-fce3-41d9-8e3f-d6a298d3c8ac" /&gt;</description>
      <category>.NET;Azure;Oslo;WCF;WF;Dublin</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=2de59a28-c44c-4d4e-8899-58004f3d3177</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2de59a28-c44c-4d4e-8899-58004f3d3177.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Thanks to everyone who came to my SOA with WF and WCF talk at <a href="http://www.oredev.org/">Oredev</a></p>
        <p>
The slides are here
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/SOA-WCF-WF.pdf">SOA-WCF-WF.pdf
(278.79 KB)</a>
        </p>
        <p>
and the demos are here
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/ServiceComposition.zip">ServiceComposition.zip
(107.08 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2de59a28-c44c-4d4e-8899-58004f3d3177" />
      </body>
      <title>Slides and demos from SOA/WF/WCF talk at Oredev</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2de59a28-c44c-4d4e-8899-58004f3d3177.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2de59a28-c44c-4d4e-8899-58004f3d3177.aspx</link>
      <pubDate>Fri, 21 Nov 2008 07:17:50 GMT</pubDate>
      <description>&lt;p&gt;
Thanks to everyone who came to my SOA with WF and WCF talk at &lt;a href="http://www.oredev.org/"&gt;Oredev&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The slides are here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/SOA-WCF-WF.pdf"&gt;SOA-WCF-WF.pdf
(278.79 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
and the demos are here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/ServiceComposition.zip"&gt;ServiceComposition.zip
(107.08 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2de59a28-c44c-4d4e-8899-58004f3d3177" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=b3840534-0f43-407d-b821-21980304bc08</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b3840534-0f43-407d-b821-21980304bc08.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was in Redmond a few weeks ago looking at the new stuff that Microsoft's Connected
System Division (CSD) were working on (WF 4.0, REST Toolkit, Oslo, Dublin). At the
end of the week I did an interview for <a href="http://blogs.msdn.com/rjacobs/">Ron
Jacobs</a> for Endpoint.tv on <a href="http://channel9.msdn.com/">Channel 9</a>. We
discussed WF 4.0, Dublin, Oslo and M - as well as 150 person <a href="http://www.develop.com/course/guerrilla-net">Guerrilla</a> courses.
You can watch it <a href=" http://channel9.msdn.com/shows/Endpoint/endpointtv-WCF-and-WF-40-First-Look-with-Richard-Blewett/" temp_href=" http://channel9.msdn.com/shows/Endpoint/endpointtv-WCF-and-WF-40-First-Look-with-Richard-Blewett/">here</a></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=b3840534-0f43-407d-b821-21980304bc08" />
      </body>
      <title>Interviewed on Channel 9</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b3840534-0f43-407d-b821-21980304bc08.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b3840534-0f43-407d-b821-21980304bc08.aspx</link>
      <pubDate>Mon, 03 Nov 2008 23:12:08 GMT</pubDate>
      <description>&lt;p&gt;
I was in Redmond a few weeks ago looking at the new stuff that Microsoft's Connected
System Division (CSD) were working on (WF 4.0, REST Toolkit, Oslo, Dublin). At the
end of the week I did an interview for &lt;a href="http://blogs.msdn.com/rjacobs/"&gt;Ron
Jacobs&lt;/a&gt; for Endpoint.tv on &lt;a href="http://channel9.msdn.com/"&gt;Channel 9&lt;/a&gt;. We
discussed WF 4.0, Dublin, Oslo and M - as well as 150 person &lt;a href="http://www.develop.com/course/guerrilla-net"&gt;Guerrilla&lt;/a&gt; courses.
You can watch it&amp;nbsp;&lt;a href=" http://channel9.msdn.com/shows/Endpoint/endpointtv-WCF-and-WF-40-First-Look-with-Richard-Blewett/" temp_href=" http://channel9.msdn.com/shows/Endpoint/endpointtv-WCF-and-WF-40-First-Look-with-Richard-Blewett/"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=b3840534-0f43-407d-b821-21980304bc08" /&gt;</description>
      <category>.NET;BizTalk;Oslo;REST;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=38703218-6179-4de2-9c34-db6fe393a67f</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,38703218-6179-4de2-9c34-db6fe393a67f.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <title>PDC Download - Part 2: .NET Services</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,38703218-6179-4de2-9c34-db6fe393a67f.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,38703218-6179-4de2-9c34-db6fe393a67f.aspx</link>
      <pubDate>Sun, 02 Nov 2008 15:10:04 GMT</pubDate>
      <description>&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;.NET Services is a block of functionality
layered on top of the Azure platform. This project has had a couple of names in the
past – BizTalk Services when it was an incubation project and then Zurich as it was
productionized.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;
&lt;o:p&gt;
&lt;font face=Calibri color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;.NET Services consists of three services:&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"&gt;
&lt;font color=#000000&gt;&lt;span style="mso-fareast-font-family: Calibri; mso-bidi-font-family: Calibri"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;font face=Calibri size=3&gt;1)&lt;/font&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face=Calibri size=3&gt;Identity&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"&gt;
&lt;font color=#000000&gt;&lt;span style="mso-fareast-font-family: Calibri; mso-bidi-font-family: Calibri"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;font face=Calibri size=3&gt;2)&lt;/font&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face=Calibri size=3&gt;The
Service Bus&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoListParagraph style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo1"&gt;
&lt;font color=#000000&gt;&lt;span style="mso-fareast-font-family: Calibri; mso-bidi-font-family: Calibri"&gt;&lt;span style="mso-list: Ignore"&gt;&lt;font face=Calibri size=3&gt;3)&lt;/font&gt;&lt;span style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face=Calibri size=3&gt;Workflow&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;o:p&gt;
&lt;font face=Calibri color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;Lets talk about identity first. Officially
named the .NET Access Control Service, this provides you a Security Token Service
(STS) that you can use to configure how different forms of authentication map into
claims (it leverages the claims construct first surfaced in WCF and now wrapped up
in Geneva). It supports user ids/passwords, Live ID, Certs and full blown federation
using WS-Trust. It also supports rule based authorization against the claim sets.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;o:p&gt;
&lt;font face=Calibri color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;The Service Bus is a component that allows
you to both listen for and send messages into the “service bus”. More concretely it
means that from inside my firewall I can listen to an internet based endpoint that
others can send messages into. It supports both unicast and multicast. The plumbing
is done by a bunch of new WCF Bindings (the word Relay in the binding indicates it
is a Service Bus binding) although there&amp;nbsp;an HTTP&amp;nbsp;based API too. Sending
messages to the internet is fairly obvious how that happens, its the listening that
is more interesting. The preferred way is to use TCP (NetTcpRelayBinding) to connect.
This parks a TCP session in the service bus which it then sends messages to you down.
However they also support HTTP although the plumbing is a bit more complex. There
they construct a Message Buffer that they send messages into then the HTTP relay listener
polls it for messages. The message buffer is not a full blown queue although it does
have some of the same characteristics of a queue. There is a very limited size and
TTL for the messages in it. Over time they may turn it into a full blown queue but
for the current CTP it is not.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;o:p&gt;
&lt;font face=Calibri color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;So what’s the point of the Service Bus? It
enables to be subscribe to internet based events (I find it hard to use the word “Cloud”
;-)) to allow loosely coupled systems over the web. It also allows the bridging of
on-premises systems to web based ones through the firewall&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;o:p&gt;
&lt;font face=Calibri color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;Finally there is the .NET Workflow Service.
This is WF in the Cloud (ok I don’t find it that hard). They provide a constrained
set of activities (currently very constrained although they are committed to providing
a much richer set. They provide HTTP Receive and Send and Service bus Send plus some
flow control and some XPath ones that allow content based routing. You deploy your
workflow into their infrastructure and can create instances of it waiting for messages
to arrive and to route them, etc. With the toolset you basically get one-click deployment
of XAML based workflows. They currently only support WF 3.5 although they will be
rolling out WF 4.0 (which is hugely different from WF 3.5 – thats the subject of another
post) in the near future.&lt;/font&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;o:p&gt;
&lt;font face=Calibri color=#000000 size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;font face=Calibri color=#000000 size=3&gt;So what does .NET Services give us? It provides
a rich set of messaging infrastructure over and above that of Windows Azure Services&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=38703218-6179-4de2-9c34-db6fe393a67f" /&gt;</description>
      <category>.NET;Azure;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=f4c218cd-6de0-42fb-ad4a-3393c49ec542</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f4c218cd-6de0-42fb-ad4a-3393c49ec542.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
          <a href="http://www.oredev.org">
            <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/oredev.jpg" border="0" />
          </a>
        </p>
        <p>
I'm going to be doing a couple of sessions at the <a href="http://www.oredev.org">Oredev</a> conference
in Sweden in November
</p>
        <p>
          <span class="normal">
            <strong>Writing REST based Systems with .NET</strong>
          </span>
        </p>
        <p>
          <span class="normal">For many, building large scale service based systems equate to
using SOAP. There is, however, another way to architect service based systems by embracing
the model the web uses - REpresentational State Transfer, or REST. .NET 3.5 introduced
a way of building the service side with WCF - however you can also use ASP.NET's infrastructure
as well. In this session we talk about what REST is, two approaches to creating REST
based services and how you can consume these services very simply with LINQ to XML.</span>
        </p>
        <span class="normal">
          <p style="PADDING-TOP: 1em">
            <span class="normal">
              <strong>Writing Service Oriented Systems with WCF and Workflow</strong>
            </span>
          </p>
          <p>
            <span class="normal">Since its launch WCF has been Microsoft's premier infrastructure
to writing SOA based systems. However one of the main benefits of Service Orientation
is combining the functionality of services to create higher order functionality which
itself is exposed as a service - namely service composition. Workflow is a very descriptive
way of showing how services are combined and in .NET 3.5 Microsoft introduced an integration
layer between WCF and Workflow to simplify the job of service composition. In this
session we examine this infrastructure and bring out both its string and weak points
with an eye to what is coming down the line in Project Oslo - Microsoft's next generation
of its SOA platform.</span>
          </p>
          <p>
            <span class="normal">Hope to see you there</span>
          </p>
        </span>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=f4c218cd-6de0-42fb-ad4a-3393c49ec542" />
      </body>
      <title>Speaking at Oredev</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f4c218cd-6de0-42fb-ad4a-3393c49ec542.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f4c218cd-6de0-42fb-ad4a-3393c49ec542.aspx</link>
      <pubDate>Tue, 16 Sep 2008 12:45:26 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.oredev.org"&gt;&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/oredev.jpg" border=0&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I'm going to be doing a couple of sessions at the &lt;a href="http://www.oredev.org"&gt;Oredev&lt;/a&gt; conference
in Sweden in November
&lt;/p&gt;
&lt;p&gt;
&lt;span class=normal&gt;&lt;strong&gt;Writing REST based Systems with .NET&lt;/strong&gt;&lt;/span&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;span class=normal&gt;For many, building large scale service based systems equate to
using SOAP. There is, however, another way to architect service based systems by embracing
the model the web uses - REpresentational State Transfer, or REST. .NET 3.5 introduced
a way of building the service side with WCF - however you can also use ASP.NET's infrastructure
as well. In this session we talk about what REST is, two approaches to creating REST
based services and how you can consume these services very simply with LINQ to XML.&lt;/span&gt;
&lt;/p&gt;
&lt;span class=normal&gt; 
&lt;p style="PADDING-TOP: 1em"&gt;
&lt;span class=normal&gt;&lt;strong&gt;Writing Service Oriented Systems with WCF and Workflow&lt;/strong&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=normal&gt;Since its launch WCF has been Microsoft's premier infrastructure
to writing SOA based systems. However one of the main benefits of Service Orientation
is combining the functionality of services to create higher order functionality which
itself is exposed as a service - namely service composition. Workflow is a very descriptive
way of showing how services are combined and in .NET 3.5 Microsoft introduced an integration
layer between WCF and Workflow to simplify the job of service composition. In this
session we examine this infrastructure and bring out both its string and weak points
with an eye to what is coming down the line in Project Oslo - Microsoft's next generation
of its SOA platform.&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span class=normal&gt;Hope to see you there&lt;/span&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=f4c218cd-6de0-42fb-ad4a-3393c49ec542" /&gt;</description>
      <category>.NET;ASP.NET;LINQ;MVC;Oslo;REST;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=b891bd0b-ad29-45cb-b8c7-1818d7886cb3</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891bd0b-ad29-45cb-b8c7-1818d7886cb3.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As promised, here are the demos from the precon myself and Dave Wheeler (get a blog
Dave) did at <a href="http://www.software-architect.co.uk/">Software Architect 2008</a>.
It was a fun day talking about security, WCF, WF, Windows Forms, WPF, Silverlight,
Ajax, ASP.NET MVC, LINQ and Oslo
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DotNetForArchitects.zip">DotNetForArchitects.zip
(791.24 KB)</a>
        </p>
        <p>
There is a text file in the demos directory in the zip that explains the role of each
of the projects in the solution
</p>
        <p>
Edit: Updated the download link so hopefully the problems people have been experiencing
will be resolved
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=b891bd0b-ad29-45cb-b8c7-1818d7886cb3" />
      </body>
      <title>Demos from Software Architect 2008 Precon</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891bd0b-ad29-45cb-b8c7-1818d7886cb3.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,b891bd0b-ad29-45cb-b8c7-1818d7886cb3.aspx</link>
      <pubDate>Fri, 06 Jun 2008 21:02:07 GMT</pubDate>
      <description>&lt;p&gt;
As promised, here are the demos from the precon myself and Dave Wheeler (get a blog
Dave) did at &lt;a href="http://www.software-architect.co.uk/"&gt;Software Architect 2008&lt;/a&gt;.
It was a fun day talking about security, WCF, WF, Windows Forms, WPF, Silverlight,
Ajax, ASP.NET MVC, LINQ&amp;nbsp;and Oslo
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DotNetForArchitects.zip"&gt;DotNetForArchitects.zip
(791.24 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
There is a text file in the demos directory in the zip that explains the role of each
of the projects in the solution
&lt;/p&gt;
&lt;p&gt;
Edit: Updated the download link so hopefully the problems people have been experiencing
will be resolved
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=b891bd0b-ad29-45cb-b8c7-1818d7886cb3" /&gt;</description>
      <category>.NET;LINQ;Oslo;SilverLight;WCF;WF;WPF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ebaa80c3-2b29-4b6b-bc1c-b648d0e5823b</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ebaa80c3-2b29-4b6b-bc1c-b648d0e5823b.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've just got back from <a href="http://www.software-architect.co.uk/">Software Architect
2008</a>. Its a great conference to speak at and an interesting change from speaking
at hard core developer conferences like <a href="http://www.devweek.com/">DevWeek</a>.
Thanks to everyone who attended my sessions - the slides and demos are below
</p>
        <p>
          <em>SOA with WCF and WF</em> - <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/SOA.zip">SOA.zip
(368.43 KB)</a></p>
        <p>
          <em>Volta</em> - <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/Volta.zip">Volta.zip
(506.21 KB)</a></p>
        <p>
The slides and demos from the pre conference workshop on <em>.NET 3.5 for architects</em> that
Dave Wheeler and me presented will be posted early next week. We have realised we
really need a guide to what all the projects are and how they relate - so we'll add
this documentation and post them
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ebaa80c3-2b29-4b6b-bc1c-b648d0e5823b" />
      </body>
      <title>Demos from Software Architect 2008</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ebaa80c3-2b29-4b6b-bc1c-b648d0e5823b.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ebaa80c3-2b29-4b6b-bc1c-b648d0e5823b.aspx</link>
      <pubDate>Fri, 06 Jun 2008 07:39:14 GMT</pubDate>
      <description>&lt;p&gt;
I've just got back from &lt;a href="http://www.software-architect.co.uk/"&gt;Software Architect
2008&lt;/a&gt;. Its a great conference to speak at and an interesting change from speaking
at hard core developer conferences like &lt;a href="http://www.devweek.com/"&gt;DevWeek&lt;/a&gt;.
Thanks to everyone who attended my sessions - the slides and demos are below
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;SOA with WCF and WF&lt;/em&gt; - &lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/SOA.zip"&gt;SOA.zip
(368.43 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Volta&lt;/em&gt; - &lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/Volta.zip"&gt;Volta.zip
(506.21 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The slides and demos from the pre conference workshop on &lt;em&gt;.NET 3.5 for architects&lt;/em&gt; that
Dave Wheeler and me presented will be posted early next week. We have realised we
really need a guide to what all the projects are and how they relate - so we'll add
this documentation and post them
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ebaa80c3-2b29-4b6b-bc1c-b648d0e5823b" /&gt;</description>
      <category>.NET;Volta;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=c42c58a8-faa6-4a1f-9ff4-896acbdd1d42</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c42c58a8-faa6-4a1f-9ff4-896acbdd1d42.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The Workflow Mapper Activity for copying data from one object to another was an interesting
project for myself, <span style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"><font color="#000000"><a href="http://headwriteline.blogspot.com/">Jörg</a></font></span> and <a href="http://blogs.thinktecture.com/cweyer/">Christian</a>.
However, none of us has the cycles to turn it into the hugely valuable activity I
think it could be. therefore, we have decided to publish the code on codeplex so hopefully
we can get community involvement to polish the functionality.
</p>
        <p>
You can find the project at 
</p>
        <p>
          <a href="http://www.codeplex.com/WFMapperActivity">http://www.codeplex.com/WFMapperActivity</a>
        </p>
        <p>
Take a look and let us know if you want to get involved in the project
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c42c58a8-faa6-4a1f-9ff4-896acbdd1d42" />
      </body>
      <title>Mapper Activity on Codeplex</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c42c58a8-faa6-4a1f-9ff4-896acbdd1d42.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c42c58a8-faa6-4a1f-9ff4-896acbdd1d42.aspx</link>
      <pubDate>Fri, 09 May 2008 04:47:56 GMT</pubDate>
      <description>&lt;p&gt;
The Workflow Mapper Activity for copying data from one object to another was an interesting
project for myself, &lt;span style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-GB; mso-fareast-language: EN-US; mso-bidi-language: AR-SA"&gt;&lt;font color=#000000&gt;&lt;a href="http://headwriteline.blogspot.com/"&gt;Jörg&lt;/a&gt;&lt;/font&gt;&lt;/span&gt; and &lt;a href="http://blogs.thinktecture.com/cweyer/"&gt;Christian&lt;/a&gt;.
However, none of us has the cycles to turn it into the hugely valuable activity I
think it could be. therefore, we have decided to publish the code on codeplex so hopefully
we can get community involvement to polish the functionality.
&lt;/p&gt;
&lt;p&gt;
You can find the project at 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.codeplex.com/WFMapperActivity"&gt;http://www.codeplex.com/WFMapperActivity&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Take a look and let us know if you want to get involved in the project
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c42c58a8-faa6-4a1f-9ff4-896acbdd1d42" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=782acafd-f394-4400-9229-feb41f29a9a7</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,782acafd-f394-4400-9229-feb41f29a9a7.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The demos from my DevWeek 2008 Postcon <em>A Day of Connected Systems with VS 2008</em> are
now here:
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DayOfCS.zip">DayOfCS.zip
(1.48 MB)</a>
        </p>
        <p>
Thanks for attending the session
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=782acafd-f394-4400-9229-feb41f29a9a7" />
      </body>
      <title>Day of Connected Systems Demos</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,782acafd-f394-4400-9229-feb41f29a9a7.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,782acafd-f394-4400-9229-feb41f29a9a7.aspx</link>
      <pubDate>Sat, 15 Mar 2008 09:47:05 GMT</pubDate>
      <description>&lt;p&gt;
The demos from my DevWeek 2008 Postcon &lt;em&gt;A Day of Connected Systems with VS 2008&lt;/em&gt; are
now here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DayOfCS.zip"&gt;DayOfCS.zip
(1.48 MB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Thanks for attending the session
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=782acafd-f394-4400-9229-feb41f29a9a7" /&gt;</description>
      <category>.NET;BizTalk;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=6bcb3ea0-1445-4025-be7e-352f177cc7cf</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6bcb3ea0-1445-4025-be7e-352f177cc7cf.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The demos for my DevWeek 2008 talk on a Developers Guide to Workflow are now available
here:
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DevGuideToWF.zip">DevGuideToWF.zip
(31.23 KB)</a>
        </p>
        <p>
Thanks a lot for attending the session
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=6bcb3ea0-1445-4025-be7e-352f177cc7cf" />
      </body>
      <title>Developers Guide to WF Demos</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6bcb3ea0-1445-4025-be7e-352f177cc7cf.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,6bcb3ea0-1445-4025-be7e-352f177cc7cf.aspx</link>
      <pubDate>Fri, 14 Mar 2008 07:46:46 GMT</pubDate>
      <description>&lt;p&gt;
The demos for my DevWeek 2008 talk on a Developers Guide to Workflow are now available
here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DevGuideToWF.zip"&gt;DevGuideToWF.zip
(31.23 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Thanks a lot for attending the session
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=6bcb3ea0-1445-4025-be7e-352f177cc7cf" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=e1c0d5c1-91c4-425a-8272-9bde78fbe2c9</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,e1c0d5c1-91c4-425a-8272-9bde78fbe2c9.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The demos from my DevWeek 2008 Silver talk about integrating WCF and WF are available
here:
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/Silver.zip">Silver.zip
(107.74 KB)</a>
        </p>
        <p>
Thanks for coming to the talk
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=e1c0d5c1-91c4-425a-8272-9bde78fbe2c9" />
      </body>
      <title>SIlver Talk Demos</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,e1c0d5c1-91c4-425a-8272-9bde78fbe2c9.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,e1c0d5c1-91c4-425a-8272-9bde78fbe2c9.aspx</link>
      <pubDate>Thu, 13 Mar 2008 11:51:43 GMT</pubDate>
      <description>&lt;p&gt;
The demos from my DevWeek 2008 Silver talk about integrating WCF and WF are available
here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/Silver.zip"&gt;Silver.zip
(107.74 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Thanks for coming to the talk
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=e1c0d5c1-91c4-425a-8272-9bde78fbe2c9" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=bb460f63-f627-4c47-8521-93e9d2daabbc</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,bb460f63-f627-4c47-8521-93e9d2daabbc.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The demos from my DevWeek 2008 Robust Long Running Workflow talk are now available
here:
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/RobustLongRunning.zip">RobustLongRunning.zip
(28.84 KB)</a>
        </p>
        <p>
Thanks for coming to the talk.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=bb460f63-f627-4c47-8521-93e9d2daabbc" />
      </body>
      <title>Robust Long Running Workflow Demos</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,bb460f63-f627-4c47-8521-93e9d2daabbc.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,bb460f63-f627-4c47-8521-93e9d2daabbc.aspx</link>
      <pubDate>Thu, 13 Mar 2008 11:48:33 GMT</pubDate>
      <description>&lt;p&gt;
The demos from my DevWeek 2008 Robust Long Running Workflow talk are now available
here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/RobustLongRunning.zip"&gt;RobustLongRunning.zip
(28.84 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Thanks for coming to the talk.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=bb460f63-f627-4c47-8521-93e9d2daabbc" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=9c484cc4-ddd7-4dfd-b8e3-d5517fe9b0a2</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9c484cc4-ddd7-4dfd-b8e3-d5517fe9b0a2.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c090e1b0-ffbc-4116-9575-c277939f2651.aspx">discussed</a> creating
robust multi-host workflow architectures with WF using the <font face="Courier New">SqlWorkflowPersistenceService</font>.
I talked about an issue with the way workflow ownership is implemented and  showed
some code that would fix the issue but that I also said was a hack. <a href="http://www.ayende.com/Blog/">Ayende</a> rightly
pointed out that for high volume systems it would be a disaster. The point of
that post was to highlight the problem.
</p>
        <p>
Ideally the workflow team will fix the persistence service to recover from abandoned
workflows more robustly - in the meantime the following stored procedure will
unlock the abandoned workflows and make then runnable. The idea is to make this a
scheduled job in the database running every few seconds - this is essentially what
BizTalk does.
</p>
        <font color="#0000ff" size="4">
          <p>
            <font face="Courier New" size="2">CREATE PROCEDURE </font>
          </p>
        </font>
        <font face="Courier New" color="#000000">dbo.ClearUnlockedWorkflows<br /></font>
        <font face="Courier New" color="#0000ff">AS<br />
BEGIN<br /></font>
        <font face="Courier New" color="#0000ff">  SET NOCOUNT ON<br /></font>
        <font color="#0000ff">
          <br />
          <font face="Courier New">  UPDATE </font>
        </font>
        <font face="Courier New">InstanceState <font color="#0000ff">Set </font>ownerID=<font color="#0000ff">null</font></font>
        <font face="Courier New">, <br />
                           ownedUntil=<font color="#0000ff">null</font>, <br />
                          
unlocked=1, 
<br />
                          
nextTimer=<font color="#0000ff">getdate</font></font>
        <font face="Courier New">()<br /></font>
        <font face="Courier New">
          <font color="#0000ff">  WHERE NOT </font>ownerID <font color="#0000ff">is
NULL and <br />
            </font>ownedUntil
&lt; <font color="#0000ff">getdate</font></font>
        <font face="Courier New">()<br /><br /></font>
        <font color="#0000ff">
          <font face="Courier New">  RETURN<br /></font>
          <font face="Courier New">END</font>
        </font>
        <p>
The only oddity in the code is the setting of the <font face="Courier New">nextTimer</font> to
the current time. The issue is that straight persistence (as opposed to unloading
on a delay) sets this value to <font face="Courier New">31st Dec 9999</font> which
is obviously not going to be reached for some time. Unfortunately the workflow will
only be scheduled due to an expired timer so I have to reset the timer such that it
will expire immediately. I can't think of any issues this would cause but if there's
a scenario I haven't thought of all comments are welcome.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=9c484cc4-ddd7-4dfd-b8e3-d5517fe9b0a2" />
      </body>
      <title>Fixing the SqlWorkflowPersistenceService Ownership Issue</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9c484cc4-ddd7-4dfd-b8e3-d5517fe9b0a2.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,9c484cc4-ddd7-4dfd-b8e3-d5517fe9b0a2.aspx</link>
      <pubDate>Tue, 12 Feb 2008 09:57:13 GMT</pubDate>
      <description>&lt;p&gt;
Recently I &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c090e1b0-ffbc-4116-9575-c277939f2651.aspx"&gt;discussed&lt;/a&gt; creating
robust multi-host workflow architectures with WF using the &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt;.
I talked about an issue with the way workflow ownership is implemented and&amp;nbsp; showed
some code that would fix the issue but that I also said was a hack. &lt;a href="http://www.ayende.com/Blog/"&gt;Ayende&lt;/a&gt; rightly
pointed out that for high volume systems it would be&amp;nbsp;a disaster. The point of
that post was to highlight the problem.
&lt;/p&gt;
&lt;p&gt;
Ideally the workflow team will fix the persistence service to recover from abandoned
workflows more robustly - in the meantime the following stored procedure&amp;nbsp;will
unlock the abandoned workflows and make then runnable. The idea is to make this a
scheduled job in the database running every few seconds - this is essentially what
BizTalk does.
&lt;/p&gt;
&lt;font color=#0000ff size=4&gt; 
&lt;p&gt;
&lt;font face="Courier New" size=2&gt;CREATE&amp;nbsp;PROCEDURE &lt;/font&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#000000&gt;dbo.ClearUnlockedWorkflows&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#0000ff&gt;AS&lt;br&gt;
BEGIN&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#0000ff&gt;&amp;nbsp; SET NOCOUNT ON&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;&amp;nbsp; UPDATE &lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;InstanceState &lt;font color=#0000ff&gt;Set &lt;/font&gt;ownerID=&lt;font color=#0000ff&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ownedUntil=&lt;font color=#0000ff&gt;null&lt;/font&gt;,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
unlocked=1, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
nextTimer=&lt;font color=#0000ff&gt;getdate&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;()&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp; WHERE NOT &lt;/font&gt;ownerID &lt;font color=#0000ff&gt;is
NULL and&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;ownedUntil
&amp;lt; &lt;font color=#0000ff&gt;getdate&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;()&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New"&gt;&amp;nbsp; RETURN&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;END&lt;/font&gt;&gt;
&lt;/font&gt; 
&lt;p&gt;
The only oddity in the code is the setting of the &lt;font face="Courier New"&gt;nextTimer&lt;/font&gt; to
the current time. The issue is that straight persistence (as opposed to unloading
on a delay) sets this value to &lt;font face="Courier New"&gt;31st Dec 9999&lt;/font&gt; which
is obviously not going to be reached for some time. Unfortunately the workflow will
only be scheduled due to an expired timer so I have to reset the timer such that it
will expire immediately. I can't think of any issues this would cause but if there's
a scenario I haven't thought of all comments are welcome.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=9c484cc4-ddd7-4dfd-b8e3-d5517fe9b0a2" /&gt;</description>
      <category>.NET;BizTalk;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=d3682735-fdcd-42a5-9ccc-c67a8d4becec</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,d3682735-fdcd-42a5-9ccc-c67a8d4becec.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For the third year running I'm going to be speaking at <a href="http://www.devweek.com/">BearPark's
DevWeek conference</a>. This year I actually managed to submit some breakout session
titles on time too.
</p>
        <p>
          <strong>
            <font size="3">Wednesday 12th March</font>
          </strong>
        </p>
        <p>
          <strong>11:30 A developer’s guide to Windows Workflow Foundation</strong>
          <br />
There are many challenges to writing software. Not least of these are lack of transparency
of code and creating software that can execute correctly in the face of process or
machine restart. Windows Workflow Foundation (WF) introduces a new way of writing
software that solves these problems and more. This session explains what WF brings
to your applications and explains how it works. Along the way we will see the major
features of WF that make it a very powerful tool in your toolkit, removing the need
for you to write a lot of complex plumbing.
</p>
        <p>
          <strong>14:00 Creating robust, long-running Workflows<br /></strong>Long-running processes have unique requirements in that they need to maintain
state over process restart; Windows Workflow Foundation (WF) enables this with its
persistence infrastructure. However, there are issues around hosting and activity
development that require attention for long running workflows to be robust. This session
looks at the design of the workflow persistence service; issues around hosting and
creating full featured asynchronous activities. This session assumes some familiarity
with WF.
</p>
        <p>
          <strong>16:00 Cross my palm with Silver – creating workflow-based WCF services</strong>
          <br />
There are very good reasons for using a workflow to implement a WCF service: workflows
can provide a clear platform for service composition (using a number of building block
services to generate functionally richer service); workflows can manage long running
stateful services without having to write your own plumbing to achieve this. This
session introduces the new Visual Studio 2008 Workflow Services. This technology,
previously known as “Silver”, provides a relatively seamless integration between WF
and WCF, enabling the service developer to concentrate on the application functionality
rather than the plumbing. This session assumes some familiarity with WF and WCF.
</p>
        <p>
          <strong>
            <font size="3">Friday 14th March - Postcon</font>
          </strong>
        </p>
        <p>
          <strong>A day of connected systems with Visual Studio 2008</strong>
          <br />
Most businesses find themselves building applications that use two or more machines
working together to produce their functionality. One of the challenges in this world,
apart from the actual business logic being implemented, is connecting the different
parts of the application in a way that best fits the environment the machines are
places – are there firewalls in place? Are some parts of the application written on
different platforms such as Java? Do the different parts of the application have to
maintain their state over machine restart? Late 2006 saw Microsoft release WCF and
WF to tackle some of these challenges. However, parts of the story were left untold
– especially the integration between the two.<br />
Visual Studio 2008 introduces a number of new features for writing service based software.
Its features build on the libraries released as part of .NET 3.0, providing an integration
layer between the two. In this pre/post conference session we start at the basics
of how WCF and WF work and then look at the various integration technologies introduced
in Visual Studio 2008.
</p>
        <p>
So if you're attending DevWeek I hope to see you there
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=d3682735-fdcd-42a5-9ccc-c67a8d4becec" />
      </body>
      <title>Speaking at DevWeek 2008</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,d3682735-fdcd-42a5-9ccc-c67a8d4becec.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,d3682735-fdcd-42a5-9ccc-c67a8d4becec.aspx</link>
      <pubDate>Wed, 06 Feb 2008 15:16:10 GMT</pubDate>
      <description>&lt;p&gt;
For the third year running I'm going&amp;nbsp;to be speaking at &lt;a href="http://www.devweek.com/"&gt;BearPark's
DevWeek conference&lt;/a&gt;. This year I actually managed to submit some breakout session
titles on time too.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=3&gt;Wednesday 12th March&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;11:30 A developer’s guide to Windows Workflow Foundation&lt;/strong&gt;
&lt;br&gt;
There are many challenges to writing software. Not least of these are lack of transparency
of code and creating software that can execute correctly in the face of process or
machine restart. Windows Workflow Foundation (WF) introduces a new way of writing
software that solves these problems and more. This session explains what WF brings
to your applications and explains how it works. Along the way we will see the major
features of WF that make it a very powerful tool in your toolkit, removing the need
for you to write a lot of complex plumbing.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;14:00 Creating robust, long-running Workflows&lt;br&gt;
&lt;/strong&gt;Long-running processes have unique requirements in that they need to maintain
state over process restart; Windows Workflow Foundation (WF) enables this with its
persistence infrastructure. However, there are issues around hosting and activity
development that require attention for long running workflows to be robust. This session
looks at the design of the workflow persistence service; issues around hosting and
creating full featured asynchronous activities. This session assumes some familiarity
with WF.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;16:00 Cross my palm with Silver – creating workflow-based WCF services&lt;/strong&gt;
&lt;br&gt;
There are very good reasons for using a workflow to implement a WCF service: workflows
can provide a clear platform for service composition (using a number of building block
services to generate functionally richer service); workflows can manage long running
stateful services without having to write your own plumbing to achieve this. This
session introduces the new Visual Studio 2008 Workflow Services. This technology,
previously known as “Silver”, provides a relatively seamless integration between WF
and WCF, enabling the service developer to concentrate on the application functionality
rather than the plumbing. This session assumes some familiarity with WF and WCF.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;font size=3&gt;Friday 14th March - Postcon&lt;/font&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;A day of connected systems with Visual Studio 2008&lt;/strong&gt;
&lt;br&gt;
Most businesses find themselves building applications that use two or more machines
working together to produce their functionality. One of the challenges in this world,
apart from the actual business logic being implemented, is connecting the different
parts of the application in a way that best fits the environment the machines are
places – are there firewalls in place? Are some parts of the application written on
different platforms such as Java? Do the different parts of the application have to
maintain their state over machine restart? Late 2006 saw Microsoft release WCF and
WF to tackle some of these challenges. However, parts of the story were left untold
– especially the integration between the two.&lt;br&gt;
Visual Studio 2008 introduces a number of new features for writing service based software.
Its features build on the libraries released as part of .NET 3.0, providing an integration
layer between the two. In this pre/post conference session we start at the basics
of how WCF and WF work and then look at the various integration technologies introduced
in Visual Studio 2008.
&lt;/p&gt;
&lt;p&gt;
So if you're attending DevWeek I hope to see you there
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=d3682735-fdcd-42a5-9ccc-c67a8d4becec" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=c090e1b0-ffbc-4116-9575-c277939f2651</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c090e1b0-ffbc-4116-9575-c277939f2651.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the most powerful features of the Windows Workflow Foundation is its ability
to automate state management of long running processes using a persistence service.
Microsoft supply a persistence service out of the box - the <font face="Courier New">SqlWorkflowPersistenceService</font>.
Unsurprisingly this persists state in SQL Server (or SQL Express).
</p>
        <p>
Once you have a persistence service more possibilities open up: different applications
can progress the same workflow instance over time; multiple hosts can process workflows
in a scale out model. This second feature needs a little investigation - there is
a gotcha hiding there you need to be aware of.
</p>
        <p>
The issue is how to stop more than one host picking up the same instance of a workflow
and processing it at the same time - imagine the workflow transfered $10,000,000 from
one account to another, you'd hardly want this happening twice. So if the possiblity
exists for multiple hosts to see the same persistence store, the persistence service
must be able to ensure only one host is executing a workflow at any one time.
</p>
        <p>
The <font face="Courier New">SqlWorkflowPersistenceService</font> handles multiple
concurrent hosts by using the concept of workflow ownership - the guid of a host (created
randomly by the persistence service constructor) is stamped against a workflow that
it is actively executing (not in an idle or completed state). Now the question comes
"what if the host dies while executing a workflow?". This is what the ownership timeout
is for. You set the ownership timeout in the constructor of the <font face="Courier New">SqlWorkflowPersistenceService</font>.
</p>
        <font size="4">
          <p>
          </p>
        </font>
        <font face="Courier New">
          <font color="#2b91af">SqlWorkflowPersistenceService</font> sql
= <br />
            </font>
        <font face="Courier New">
          <font color="#0000ff">new</font>
          <font color="#2b91af">SqlWorkflowPersistenceService</font>(CONN, <br />
                                              </font>
        <font face="Courier New">
          <font color="#0000ff">true</font>, <br />
                                              <strong><font size="3"><font color="#2b91af">TimeSpan</font>.FromSeconds(10),</font></strong> <font color="#2b91af"><br />
                                              TimeSpan</font></font>
        <font face="Courier New">.FromSeconds(5));</font>
        <p>
          <font face="Courier New">workflowRuntime.AddService(sql);</font>
        </p>
        <p>
          <font face="Courier New">
          </font>
          <font size="4">
            <font size="2">Here the third parameter
specifies how long a host is allowed to run a workflow before persistence occurs.
If the host takes longer than this then it will get an error when it atempts to persist.
The fourth parameter is the polling interval for how often the persistence service
will check for expired timers.</font>
          </font>
        </p>
        <p>
          <font size="4">
            <font size="2">Now the idea is that if a host dies then it's lock will
timeout and another host can pick up the work. There is a problem, however, in the
implementation. The persistence service only looks for expired ownership locks when
it first starts - not when it polls for expired timers. Therefore, for a workflow
instance whose host has died mid-processing, it will only recover if a new host instance
starts after the timeout has occurred.</font>
          </font>
        </p>
        <p>
          <font size="4">
            <font size="2">So how can you make this more robust? Well we need a
way to explicitly load the workflows that have had their ownership expire - unfortunately
there is no exposed method to do this on the <font face="Courier New">SqlWorkflowPersistenceService</font>.
Instead we have to get all the workflows, catch the exception if we load a locked
one and unload any that aren't ready to run. Here is an example:</font>
          </font>
        </p>
        <font size="4">
          <font size="4">
            <p>
            </p>
          </font>
          <font face="Courier New">
            <font size="2">
              <font color="#2b91af">TimerCallback</font> cb
= </font>
            <font color="#0000ff" size="2">delegate<br /></font>
          </font>
          <font face="Courier New" size="2">{<br />
  </font>
          <font size="2">
            <font color="#008000">
              <font face="Courier New">// get
all the persisted workflows<br /></font>
            </font>
            <font face="Courier New">
              <font color="#0000ff">  foreach</font> (<font color="#0000ff">var</font> item <font color="#0000ff">in</font></font>
          </font>
          <font face="Courier New" size="2"> sql.GetAllWorkflows())<br />
  </font>
          <font face="Courier New" size="2">{<br />
    </font>
          <font color="#0000ff">
            <font face="Courier New" size="2">try<br /></font>
          </font>
          <font face="Courier New" size="2">    {<br /></font>
          <font color="#008000">
            <font face="Courier New" size="2">     
// load the workflow - this will throw a WorkflowOwnershipException if 
<br /></font>
          </font>
          <font size="2">
            <font color="#008000">
              <font face="Courier New">     
// the workflow is currently owned<br /></font>
            </font>
            <font face="Courier New" color="#2b91af">     
WorkflowInstance</font>
          </font>
          <font face="Courier New" size="2"> inst = workflowRuntime.GetWorkflow(item.WorkflowInstanceId);<br /></font>
          <font color="#008000">
            <font face="Courier New">
              <br />
              <font size="2">      // Unload workflow if its still idle
on a timer<br /></font>
            </font>
          </font>
          <font face="Courier New">
            <font size="2">
              <font color="#2b91af">     
DateTime</font> timerExpiry = (<font color="#2b91af">DateTime</font></font>
          </font>
          <font size="2">
            <font face="Courier New">)item.NextTimerExpiration;<br /></font>
            <font face="Courier New">
              <font color="#0000ff">     
if</font> (timerExpiry &gt; <font color="#2b91af">DateTime</font></font>
          </font>
          <font face="Courier New" size="2">.Now)<br /></font>
          <font face="Courier New" size="2">      {<br /></font>
          <font face="Courier New" size="2">        inst.Unload();<br /></font>
          <font face="Courier New" size="2">      }<br /></font>
          <font size="2">
            <font face="Courier New">    }<br /></font>
            <font face="Courier New">
              <font color="#0000ff">    catch</font>(<font color="#2b91af">WorkflowOwnershipException</font></font>
          </font>
          <font face="Courier New" size="2"> e)<br /></font>
          <font face="Courier New" size="2">    {<br /></font>
          <font color="#008000">
            <font face="Courier New" size="2">     
// Loaded a workflow locked by another instance<br /></font>
          </font>
          <font face="Courier New" size="2">    }<br /></font>
          <font face="Courier New" size="2">  }<br /></font>
          <font size="2">
            <font face="Courier New">};<br /><br /></font>
            <font face="Courier New">
              <font color="#2b91af">Timer</font> t = <font color="#0000ff">new</font><font color="#2b91af">Timer</font>(cb, <font color="#0000ff">null</font>,
0, 1000);</font>
          </font>
          <p>
            <font face="Courier New">
              <font size="4">
                <font face="Verdana" size="2">So this code
will attempt to load workflow instances with expired locks every second. Is it a hack?
Yes. But without one of two things in the <font face="Courier New">SqlWorkflowPersistenceService</font> its
the sort of code you have to write to pick up unlocked workflow instances robustly.
The workflow team could:</font>
              </font>
            </font>
          </p>
          <ul>
            <li>
              <font face="Courier New">
                <font size="4">
                  <font face="Verdana" size="2">Check for expired
ownership locks in the stored procedure that checks for timer expiration</font>
                </font>
              </font>
            </li>
            <li>
              <font face="Courier New">
                <font size="4">
                  <font face="Verdana" size="2">Provide a method
on the persistence service that explicitly allows the loading of unlocked workflow
instances</font>
                </font>
              </font>
            </li>
          </ul>
          <p>
            <font face="Courier New">
              <font size="4">
                <font face="Verdana" size="2">Maybe in the
next version :-)</font>
              </font>
            </font>
          </p>
        </font>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c090e1b0-ffbc-4116-9575-c277939f2651" />
      </body>
      <title>Scaleable Workflow Persistence and Ownership</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c090e1b0-ffbc-4116-9575-c277939f2651.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c090e1b0-ffbc-4116-9575-c277939f2651.aspx</link>
      <pubDate>Mon, 04 Feb 2008 11:07:39 GMT</pubDate>
      <description>&lt;p&gt;
One of the most powerful features of the Windows Workflow Foundation is its ability
to automate state management of long running processes using a persistence service.
Microsoft supply a persistence service out of the box - the &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt;.
Unsurprisingly this persists state in SQL Server (or SQL Express).
&lt;/p&gt;
&lt;p&gt;
Once you have a persistence service more possibilities open up: different applications
can progress the same workflow instance over time; multiple hosts can process workflows
in a scale out model. This second feature needs a little investigation - there is
a gotcha hiding there you need to be aware of.
&lt;/p&gt;
&lt;p&gt;
The issue is how to stop more than one host picking up the same instance of a workflow
and processing it at the same time - imagine the workflow transfered $10,000,000 from
one account to another, you'd hardly want this happening twice. So if the possiblity
exists for multiple hosts to see the same persistence store, the persistence service
must be able to ensure only one host is executing a workflow at any one time.
&lt;/p&gt;
&lt;p&gt;
The &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt; handles multiple
concurrent hosts by using the concept of workflow ownership - the guid of a host (created
randomly by the persistence service constructor) is stamped against a workflow that
it is actively executing (not in an idle or completed state). Now the question comes
"what if the host dies while executing a workflow?". This is what the ownership timeout
is for. You set the ownership timeout in the constructor of the &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt;.
&lt;/p&gt;
&lt;font size=4&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;SqlWorkflowPersistenceService&lt;/font&gt; sql
=&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;new&lt;/font&gt; &lt;font color=#2b91af&gt;SqlWorkflowPersistenceService&lt;/font&gt;(CONN,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;true&lt;/font&gt;,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;strong&gt;&lt;font size=3&gt;&lt;font color=#2b91af&gt;TimeSpan&lt;/font&gt;.FromSeconds(10),&lt;/font&gt;&lt;/strong&gt;&amp;nbsp;&lt;font color=#2b91af&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TimeSpan&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;.FromSeconds(5));&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;workflowRuntime.AddService(sql);&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;font size=4&gt;&lt;font size=2&gt;Here the third parameter
specifies how long a host is allowed to run a workflow before persistence occurs.
If the host takes longer than this then it will get an error when it atempts to persist.
The fourth parameter is the polling interval for how often the persistence service
will check for expired timers.&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font size=2&gt;Now the idea is that if a host dies then it's lock will
timeout and another host can pick up the work. There is a problem, however, in the
implementation. The persistence service only looks for expired&amp;nbsp;ownership locks&amp;nbsp;when
it first starts - not when it polls for expired timers. Therefore, for a workflow
instance whose host has died mid-processing, it will only recover if a new host instance
starts after the timeout has occurred.&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;font size=2&gt;So how can you make this more robust? Well we need a way
to explicitly load the workflows that have had their ownership expire - unfortunately
there is no exposed method to do this on the &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt;.
Instead we have to get all the workflows, catch the exception if we load a locked
one and unload any that aren't ready to run. Here is an example:&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;font size=4&gt;&lt;font size=4&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;&lt;font color=#2b91af&gt;TimerCallback&lt;/font&gt; cb
= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;delegate&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt;{&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font size=2&gt;&lt;font color=#008000&gt;&lt;font face="Courier New"&gt;// get all
the persisted workflows&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp; foreach&lt;/font&gt; (&lt;font color=#0000ff&gt;var&lt;/font&gt; item &lt;font color=#0000ff&gt;in&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; sql.GetAllWorkflows())&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New" size=2&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font color=#0000ff&gt;&lt;font face="Courier New" size=2&gt;try&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font color=#008000&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// load the workflow - this will throw a WorkflowOwnershipException if 
&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#008000&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// the workflow is currently owned&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color=#2b91af&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
WorkflowInstance&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; inst = workflowRuntime.GetWorkflow(item.WorkflowInstanceId);&lt;br&gt;
&lt;/font&gt;&lt;font color=#008000&gt;&lt;font face="Courier New"&gt;
&lt;br&gt;
&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Unload workflow if its still idle on
a timer&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;&lt;font color=#2b91af&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
DateTime&lt;/font&gt; timerExpiry = (&lt;font color=#2b91af&gt;DateTime&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;)item.NextTimerExpiration;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/font&gt; (timerExpiry &amp;gt; &lt;font color=#2b91af&gt;DateTime&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt;.Now)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;inst.Unload();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch&lt;/font&gt;(&lt;font color=#2b91af&gt;WorkflowOwnershipException&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; e)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font color=#008000&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
// Loaded a workflow locked by another instance&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" size=2&gt;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;};&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;Timer&lt;/font&gt; t = &lt;font color=#0000ff&gt;new&lt;/font&gt; &lt;font color=#2b91af&gt;Timer&lt;/font&gt;(cb, &lt;font color=#0000ff&gt;null&lt;/font&gt;,
0, 1000);&lt;/font&gt;&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font size=4&gt;&lt;font face=Verdana size=2&gt;So this code will
attempt to load workflow instances with expired locks every second. Is it a hack?
Yes.&amp;nbsp;But without one of two things in the &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt; its
the sort of code you have to write to pick up unlocked workflow instances robustly.
The workflow team could:&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;font face="Courier New"&gt;&lt;font size=4&gt;&lt;font face=Verdana size=2&gt;Check for expired
ownership locks in the stored procedure that checks for timer expiration&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;font face="Courier New"&gt;&lt;font size=4&gt;&lt;font face=Verdana size=2&gt;Provide a method on
the persistence service that explicitly allows the loading of unlocked workflow instances&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font size=4&gt;&lt;font face=Verdana size=2&gt;Maybe in the next
version :-)&lt;/font&gt;
&lt;/p&gt;
&lt;/font&gt;&gt;&gt;&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c090e1b0-ffbc-4116-9575-c277939f2651" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=400f2d30-6402-438c-b20f-d0639b832940</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,400f2d30-6402-438c-b20f-d0639b832940.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blogs.thinktecture.com/cweyer/">Christian</a> noticed a bug in my
Async Activity base class that I talked about <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx">here</a> and <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,abe40cae-d1ad-44d5-843a-b1b3b7aec9d7.aspx">here</a>.
The latest code is <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass12.zip">here</a></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=400f2d30-6402-438c-b20f-d0639b832940" />
      </body>
      <title>Async Activity Helper Update</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,400f2d30-6402-438c-b20f-d0639b832940.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,400f2d30-6402-438c-b20f-d0639b832940.aspx</link>
      <pubDate>Fri, 04 Jan 2008 17:20:57 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blogs.thinktecture.com/cweyer/"&gt;Christian&lt;/a&gt; noticed a bug in my
Async Activity base class that I talked about &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,abe40cae-d1ad-44d5-843a-b1b3b7aec9d7.aspx"&gt;here&lt;/a&gt;.
The latest code is &lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass12.zip"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=400f2d30-6402-438c-b20f-d0639b832940" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=7fe1f77f-b4fc-40c3-8dd0-699123454fcd</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,7fe1f77f-b4fc-40c3-8dd0-699123454fcd.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When working with WF I always find it useful having a BizTalk background. Issues that
are reasonably well known in BizTalk are not immediatedly apparent in Workflow unless
you know they are part and parcel of that style of programming. 
</p>
        <p>
One issue in BizTalk is where you are waiting for a number of messages to start off
some processing and you don't know in which order they are going to arrive. In this
situation you use a Parallel Shape and put activating receives in the branches initializing
the same correlation set. The orchestration engine understands what you are trying
to do and creates a convoy for the remaining messages when the first one arrives.
This is known as a Concurrent Parallel Receive. You don't leave the parallel shape
until the all the messages have arrived and the convoy ensures that the remaining
messages are routed to the same orchestration instance. 
</p>
        <p>
There is, however, an inherent race condition in this architecture in that: if two
messages arrive simultaneously, due to the asynchronous nature of BizTalk, both messages
could be processed before the orchestration engine has a chance to set up the convoy
infrastructure. We will end up with two instances of the orchestration both
waiting for messages that will never arrive. All you can do is put timeouts in place
to ensure your orchestrations can recover from that situation and flag the fact that
the messages require resubmitting.
</p>
        <p>
With Workflow Services we essentially have the same issue waiting for us. Lets set
up the workflow ...
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/ParallelReceives.jpg" border="0" />
        </p>
        <p>
If we call this from a client as follows:
</p>
        <font size="4">
          <p>
          </p>
        </font>
        <font face="Courier New">
          <font color="#2b91af">PingClient</font> proxy
= <font color="#0000ff">new</font><font color="#2b91af">PingClient</font></font>
        <font face="Courier New">();<br /></font>
        <font size="4">
          <font face="Courier New" size="2">proxy.Ping1();<br />
proxy.Ping2();</font>
        </font>
        <p>
then everything works ok - in fact it works irrespective of the order the operations
are called in, that's the nature of this pattern. It works because by the time we
make the second call, the first has completed and the context is now cached on the
proxy.
</p>
        <p>
But lets make the client a bit more complex:
</p>
        <font size="4">
          <p>
          </p>
        </font>
        <font face="Courier New">
          <font color="#0000ff">static</font>
          <font color="#2b91af">IDictionary</font>&lt;<font color="#0000ff">string</font>, <font color="#0000ff">string</font>&gt;
ctx = <font color="#0000ff">null</font></font>
        <font face="Courier New">;<br /></font>
        <font face="Courier New">
          <font color="#0000ff">static</font>
          <font color="#0000ff">void</font> Main(<font color="#0000ff">string</font></font>
        <font face="Courier New">[]
args)<br /></font>
        <font face="Courier New">{<br /></font>
        <font face="Courier New">
          <font color="#2b91af">  PingClient</font> proxy
= <font color="#0000ff">new</font><font color="#2b91af">PingClient</font></font>
        <font face="Courier New">();<br /></font>
        <font face="Courier New">
          <font color="#2b91af">  IContextManager</font> mgr
= ((<font color="#2b91af">IChannel</font>)proxy.InnerChannel).GetProperty&lt;<font color="#2b91af">IContextManager</font></font>
        <font face="Courier New">&gt;();<br /><br /></font>
        <font face="Courier New">
          <font color="#2b91af">  Thread</font> t = <font color="#0000ff">new</font><font color="#2b91af">Thread</font></font>
        <font face="Courier New">(DoIt);<br />
  <font face="Courier New">t.Start();</font><p><br /></p></font>
        <font face="Courier New">
          <font color="#0000ff">  if</font> (ctx != <font color="#0000ff">null</font></font>
        <font face="Courier New">)<br /></font>
        <font face="Courier New">  {<br /></font>
        <font face="Courier New">    mgr.SetContext(ctx);<br />
  </font>
        <font face="Courier New">}</font>
        <p>
          <font face="Courier New">  proxy.Ping1();<br /></font>
          <font face="Courier New">  ctx = mgr.GetContext();<br /><br /></font>
          <font face="Courier New">
            <font color="#2b91af">  Console</font>.WriteLine(<font color="#a31515">"press
enter to exit"</font></font>
          <font face="Courier New">);<br /></font>
          <font face="Courier New" color="#2b91af">  Console</font>
          <font face="Courier New">.ReadLine();<br /></font>
          <font face="Courier New">}</font>
        </p>
        <p>
          <font face="Courier New">
            <font color="#0000ff">static</font>
            <font color="#0000ff">void</font>
          </font>
          <font face="Courier New"> DoIt()<br /></font>
          <font face="Courier New">{<br /></font>
          <font face="Courier New">
            <font color="#2b91af">  PingClient</font> proxy
= <font color="#0000ff">new</font><font color="#2b91af">PingClient</font></font>
          <font face="Courier New">();<br /></font>
          <font face="Courier New">
            <font color="#2b91af">  IContextManager</font> mgr
= ((<font color="#2b91af">IChannel</font>)proxy.InnerChannel).GetProperty&lt;<font color="#2b91af">IContextManager</font></font>
          <font face="Courier New">&gt;();<br /></font>
          <font face="Courier New">
            <font color="#0000ff">
              <br />
  if</font> (ctx != <font color="#0000ff">null</font></font>
          <font face="Courier New">)<br /></font>
          <font face="Courier New">  {<br /></font>
          <font face="Courier New">    mgr.SetContext(ctx);<br /></font>
          <font face="Courier New">  }<br /></font>
          <font face="Courier New">  proxy.Ping2();<br /></font>
          <font face="Courier New">  ctx = mgr.GetContext();<br /></font>
          <font face="Courier New">}</font>
        </p>
        <p>
Here we make the two calls on different proxies on different threads. A successful
call stores the context in the static <font face="Courier New">ctx</font> field. Now
a proxy will use the context if it has already been set, otherwise it assumes that
it is the first call. So here the race condition has made its way all the way back
to the client. There are things we could do about this in the client code (taking
a lock out while we're making the call so we complete one and store the context before
the other checks to see if the context is <font face="Courier New">null</font>), however,
that really isn't the point. The messages may come from two separate client applications
which both check a database for the context. Again we have an inherent race condition
that we need to put architecture in place to detect and recover from. It would be
nice to put the <font face="Courier New">ParallelActivity</font> in a <font face="Courier New">ListenActivity</font> with
a timeout <font face="Courier New">DelayActivity</font>. However you can't do this
because a <font face="Courier New">ParallelActivity</font> does not implement <font face="Courier New">IEventActivity</font> and
so the <font face="Courier New">ListenActivity</font> validation will fail (the first
activity in a branch must implement <font face="Courier New">IEventActivity</font>).
We therefore have to put each receive in its own <font face="Courier New">ListenActivity</font> and
time out the waits individually.
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/parallelwithlisten.jpg" border="0" />
        </p>
        <p>
So is the situation pretty much the same for both WF and BizTalk? Well not really.
The BizTalk window of failure is much smaller than the WF one as the race condition
is isolated server side. Because WF ropes the client into message correlation the
client has to receive the context and put it somewhere visible to other interested
parties before the race condition is resolved.
</p>
        <p>
Hopefully <a href="http://blogs.msdn.com/biztalk_server_team_blog/archive/2007/10/30/oslo-is-announced.aspx">Oslo</a> will
bring data orientated correlation to the WF world<font size="4"></font></p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=7fe1f77f-b4fc-40c3-8dd0-699123454fcd" />
      </body>
      <title>Workflow Services, BizTalk, Correlation and Race Conditions</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,7fe1f77f-b4fc-40c3-8dd0-699123454fcd.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,7fe1f77f-b4fc-40c3-8dd0-699123454fcd.aspx</link>
      <pubDate>Fri, 14 Dec 2007 10:31:35 GMT</pubDate>
      <description>&lt;p&gt;
When working with WF I always find it useful having a BizTalk background. Issues that
are reasonably well known in BizTalk are not immediatedly apparent in Workflow unless
you know they are part and parcel of that style of programming. 
&lt;/p&gt;
&lt;p&gt;
One issue in BizTalk is where you are waiting for a number of messages to start off
some processing and you don't know in which order they are going to arrive. In this
situation you use a Parallel Shape and put activating receives in the branches initializing
the same correlation set. The orchestration engine understands what you are trying
to do and creates a convoy for the remaining messages when the first one arrives.
This is known as a Concurrent Parallel Receive. You don't leave the parallel shape
until the all the messages have arrived and the convoy ensures that the remaining
messages are routed to the same orchestration instance. 
&lt;/p&gt;
&lt;p&gt;
There is, however, an inherent race condition in this architecture in that: if two
messages arrive simultaneously, due to the asynchronous nature of BizTalk, both messages
could be processed before the orchestration engine has a chance to set up the convoy
infrastructure. We&amp;nbsp;will end up with&amp;nbsp;two instances of the orchestration both
waiting for messages that will never arrive. All you can do is put timeouts in place
to ensure your orchestrations can recover from that situation and flag the fact that
the messages require resubmitting.
&lt;/p&gt;
&lt;p&gt;
With Workflow Services we essentially have the same issue waiting for us. Lets set
up the workflow ...
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/ParallelReceives.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
If we call this from a client as follows:
&lt;/p&gt;
&lt;font size=4&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;PingClient&lt;/font&gt; proxy = &lt;font color=#0000ff&gt;new&lt;/font&gt; &lt;font color=#2b91af&gt;PingClient&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;();&lt;br&gt;
&lt;/font&gt;&lt;font size=4&gt;&lt;font face="Courier New" size=2&gt;proxy.Ping1();&lt;br&gt;
proxy.Ping2();&lt;/font&gt;&lt;/font&gt;&gt;
&lt;p&gt;
then everything works ok - in fact it works irrespective of the order the operations
are called in, that's the nature of this pattern. It works because by the time we
make the second call, the first has completed and the context is now cached on the
proxy.
&lt;/p&gt;
&lt;p&gt;
But lets make the client a bit more complex:
&lt;/p&gt;
&lt;font size=4&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;static&lt;/font&gt; &lt;font color=#2b91af&gt;IDictionary&lt;/font&gt;&amp;lt;&lt;font color=#0000ff&gt;string&lt;/font&gt;, &lt;font color=#0000ff&gt;string&lt;/font&gt;&amp;gt;
ctx = &lt;font color=#0000ff&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;;&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;static&lt;/font&gt; &lt;font color=#0000ff&gt;void&lt;/font&gt; Main(&lt;font color=#0000ff&gt;string&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;[]
args)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;&amp;nbsp; PingClient&lt;/font&gt; proxy
= &lt;font color=#0000ff&gt;new&lt;/font&gt; &lt;font color=#2b91af&gt;PingClient&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;&amp;nbsp; IContextManager&lt;/font&gt; mgr
= ((&lt;font color=#2b91af&gt;IChannel&lt;/font&gt;)proxy.InnerChannel).GetProperty&amp;lt;&lt;font color=#2b91af&gt;IContextManager&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;&amp;nbsp; Thread&lt;/font&gt; t = &lt;font color=#0000ff&gt;new&lt;/font&gt; &lt;font color=#2b91af&gt;Thread&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;(DoIt);&lt;br&gt;
&amp;nbsp; &lt;font face="Courier New"&gt;t.Start();&lt;/font&gt;&gt;
&lt;p&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;&amp;nbsp; if&lt;/font&gt; (ctx != &lt;font color=#0000ff&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mgr.SetContext(ctx);&lt;br&gt;
&amp;nbsp; &lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp; proxy.Ping1();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; ctx = mgr.GetContext();&lt;br&gt;
&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;&amp;nbsp; Console&lt;/font&gt;.WriteLine(&lt;font color=#a31515&gt;"press
enter to exit"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New" color=#2b91af&gt;&amp;nbsp; Console&lt;/font&gt;&lt;font face="Courier New"&gt;.ReadLine();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;static&lt;/font&gt; &lt;font color=#0000ff&gt;void&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt; DoIt()&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;{&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;&amp;nbsp; PingClient&lt;/font&gt; proxy
= &lt;font color=#0000ff&gt;new&lt;/font&gt; &lt;font color=#2b91af&gt;PingClient&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#2b91af&gt;&amp;nbsp; IContextManager&lt;/font&gt; mgr
= ((&lt;font color=#2b91af&gt;IChannel&lt;/font&gt;)proxy.InnerChannel).GetProperty&amp;lt;&lt;font color=#2b91af&gt;IContextManager&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;gt;();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;
&lt;br&gt;
&amp;nbsp; if&lt;/font&gt; (ctx != &lt;font color=#0000ff&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;)&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; {&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mgr.SetContext(ctx);&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; }&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; proxy.Ping2();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&amp;nbsp; ctx = mgr.GetContext();&lt;br&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Here we make the two calls on different proxies on different threads. A successful
call stores the context in the static &lt;font face="Courier New"&gt;ctx&lt;/font&gt; field. Now
a proxy will use the context if it has already been set, otherwise it assumes that
it is the first call. So here the race condition has made its way all the way back
to the client. There are things we could do about this in the client code (taking
a lock out while we're making the call so we complete one and store the context before
the other checks to see if the context is &lt;font face="Courier New"&gt;null&lt;/font&gt;), however,
that really isn't the point. The messages may come from two separate client applications
which both check a database for the context. Again we have an inherent race condition
that we need to put architecture in place to detect and recover from. It would be
nice to put the &lt;font face="Courier New"&gt;ParallelActivity&lt;/font&gt; in a &lt;font face="Courier New"&gt;ListenActivity&lt;/font&gt; with
a timeout &lt;font face="Courier New"&gt;DelayActivity&lt;/font&gt;. However you can't do this
because a &lt;font face="Courier New"&gt;ParallelActivity&lt;/font&gt; does not implement &lt;font face="Courier New"&gt;IEventActivity&lt;/font&gt; and
so the &lt;font face="Courier New"&gt;ListenActivity&lt;/font&gt; validation will fail (the first
activity in a branch must implement &lt;font face="Courier New"&gt;IEventActivity&lt;/font&gt;).
We therefore have to put each receive in its own &lt;font face="Courier New"&gt;ListenActivity&lt;/font&gt; and
time out the waits individually.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/parallelwithlisten.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
So is the situation pretty much the same for both WF and BizTalk? Well not really.
The BizTalk window of failure is much smaller than&amp;nbsp;the WF one as the race condition
is isolated server side. Because WF ropes the client into message correlation the
client has to receive the context and put it somewhere visible to other interested
parties before the race condition is resolved.
&lt;/p&gt;
&lt;p&gt;
Hopefully &lt;a href="http://blogs.msdn.com/biztalk_server_team_blog/archive/2007/10/30/oslo-is-announced.aspx"&gt;Oslo&lt;/a&gt; will
bring data orientated correlation to the WF world&lt;font size=4&gt;
&lt;/p&gt;
&gt;&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=7fe1f77f-b4fc-40c3-8dd0-699123454fcd" /&gt;</description>
      <category>.NET;BizTalk;WCF;WF;Oslo</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=900a5373-a534-41cc-8eda-1dfa93f0c931</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,900a5373-a534-41cc-8eda-1dfa93f0c931.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yesterday I announced the <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2f6c28f6-dc6e-49e1-afd6-944054c6bd9e.aspx">release
of the MapperActivity</a>. I said I'd clean up the source code and post it. 
</p>
        <p>
Two things are worth noting: 
</p>
        <ol>
          <li>
The dependency on the CodeProject Type Browser has gone</li>
          <li>
There is a known issue where you can map more than one source element to the same
destination - in this case the last mapping you create will win. We will fix this
in a subsequent release.</li>
        </ol>
        <p>
Here's the latest version with the code
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/MapperActivityLibrary.zip">MapperActivityLibrary.zip
(933.62 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=900a5373-a534-41cc-8eda-1dfa93f0c931" />
      </body>
      <title>MapperActivity Code</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,900a5373-a534-41cc-8eda-1dfa93f0c931.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,900a5373-a534-41cc-8eda-1dfa93f0c931.aspx</link>
      <pubDate>Tue, 11 Dec 2007 08:31:41 GMT</pubDate>
      <description>&lt;p&gt;
Yesterday I announced the &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2f6c28f6-dc6e-49e1-afd6-944054c6bd9e.aspx"&gt;release
of the MapperActivity&lt;/a&gt;. I said I'd clean up the source code and post it. 
&lt;/p&gt;
&lt;p&gt;
Two things are worth noting: 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
The dependency on the CodeProject&amp;nbsp;Type Browser has gone&lt;/li&gt;
&lt;li&gt;
There is a known issue where you can map more than one source element to the same
destination - in this case the last mapping you create will win. We will fix this
in a subsequent release.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Here's the latest version with the code
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/MapperActivityLibrary.zip"&gt;MapperActivityLibrary.zip
(933.62 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=900a5373-a534-41cc-8eda-1dfa93f0c931" /&gt;</description>
      <category>.NET;BizTalk;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=2f6c28f6-dc6e-49e1-afd6-944054c6bd9e</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2f6c28f6-dc6e-49e1-afd6-944054c6bd9e.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the neat things you can do in BizTalk is to create a map that takes one kind
of XML message and transforms it into another. They basically are a wrapper over XSLT
and its extension infrastructure. The tool you use to create maps is the BizTalk mapper.
In this tool you load in a source and destination schema - which get displayed in
treeviews and then you drag elements from the source to the destination to describe
how to build the destination message.
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/BTSMapper.jpg" border="0" />
        </p>
        <p>
Now, in WF - especially when using Silver (the WF/WCF integration layer introduced
in .NET 3.5) - you tend to spend alot of time taking data from one object and putting
it into another as different objects are used to serialize and deserialize messages
received and sent via WCF. This sounds alot like what the BizTalk Mapper does, but
with objects rather than XML messages.
</p>
        <p>
I was recently teaching Guerrilla Connected Systems (which has now been renamed <a href="http://www.develop.com/us/training/course.aspx?id=445">Guerrilla
Enterprise.NET</a>) and <a href="http://blogs.thinktecture.com/cweyer/">Christian
Weyer</a> was doing a guest talk on <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> and <a href="http://labs.biztalk.net/">BizTalk
Services</a>. Afterwards, Christian and me were bemoaning the amount of mundane code
you get forced to write in Silver and how sad it was that WF doesn't have a mapper.
So we decided to build one. Unfortunately neither myself nor Christian are particularly
talented when it comes to UI - but we knew someone who was: <a href="http://headwriteline.blogspot.com/">Jörg
Neumann</a>. So with Jörg doing the UI, myself writing the engine and Christian acting
as our user/tester we set to work.
</p>
        <p>
The result is the <font face="Courier New">MapperActivity</font>. The <font face="Courier New">MapperActivity</font> requires
you to specify the <font face="Courier New">SourceType</font> and <font face="Courier New">DestinationType</font> -
we used the <a href="http://www.codeproject.com/KB/cs/WFTypeBrowser.aspx">Type Browser
from CodeProject</a> for this. Then you can edit the <font face="Courier New">Mappings</font> which
brings up the mapping tool
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WFMapper.jpg" border="0" />
        </p>
        <p>
You drag members (properties or fields) from the left hand side and drop them on type
compatible members (properties or fields) on the right hand side.
</p>
        <p>
Finally you need to databind the <font face="Courier New">SourceObject</font> and <font face="Courier New">DestinationObject</font><font face="Verdana"> to
tell the mapper where the data comes from and where the data is going</font>. You
can optionally get the <font face="Courier New">MapperActivity</font> to create the
destination object tree if it doesn't exist using the <font face="Courier New">CanCreateDestination</font> property.
Here's the full property grid:
</p>
        <p>
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WFMapProps.jpg" border="0" />
        </p>
        <p>
And thanks to <a href="http://masteringbiztalk.com/blogs/jon/">Jon Flanders</a> for
letting me crib his custom <font face="Courier New">PropertyDescriptor</font> implementation
(why on earth don't we have a public one in the framework?). You need one of these
when creating extender properties (the <font face="Courier New">SourceObject</font> and <font face="Courier New">DestinationObject</font> properties
change type based on the <font face="Courier New">SourceType</font> and <font face="Courier New">DestinationType</font> respectively).
</p>
        <p>
Here is the activity - I'll clean up the code before posting that.
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/MapperActivity.zip">MapperActivity.zip
(37.78 KB)</a>
        </p>
        <p>
Feedback always appreciated
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2f6c28f6-dc6e-49e1-afd6-944054c6bd9e" />
      </body>
      <title>Giving Birth - The WF MapperActivity</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2f6c28f6-dc6e-49e1-afd6-944054c6bd9e.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2f6c28f6-dc6e-49e1-afd6-944054c6bd9e.aspx</link>
      <pubDate>Mon, 10 Dec 2007 21:56:07 GMT</pubDate>
      <description>&lt;p&gt;
One of the neat things you can do in BizTalk is to create a map that takes one kind
of XML message and transforms it into another. They basically are a wrapper over XSLT
and its extension infrastructure. The tool you use to create maps is the BizTalk mapper.
In this tool you load in a source and destination schema - which get displayed in
treeviews and then you drag elements from the source to the destination to describe
how to build the destination message.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/BTSMapper.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Now, in WF - especially when using Silver (the WF/WCF integration layer introduced
in .NET 3.5) - you tend to spend alot of time taking data from one object and putting
it into another as different objects are used to serialize and deserialize messages
received and sent via WCF. This sounds alot like what the BizTalk Mapper does, but
with objects rather than XML messages.
&lt;/p&gt;
&lt;p&gt;
I was recently teaching Guerrilla Connected Systems (which has now been renamed &lt;a href="http://www.develop.com/us/training/course.aspx?id=445"&gt;Guerrilla
Enterprise.NET&lt;/a&gt;) and &lt;a href="http://blogs.thinktecture.com/cweyer/"&gt;Christian
Weyer&lt;/a&gt; was doing a guest talk on &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; and &lt;a href="http://labs.biztalk.net/"&gt;BizTalk
Services&lt;/a&gt;. Afterwards, Christian and me were bemoaning the amount of mundane code
you get forced to write in Silver and how sad it was that WF doesn't have a mapper.
So we decided to build one. Unfortunately neither myself nor Christian are particularly
talented when it comes to UI - but we knew someone who was: &lt;a href="http://headwriteline.blogspot.com/"&gt;Jörg
Neumann&lt;/a&gt;. So with Jörg doing the UI, myself writing the engine and Christian acting
as our user/tester we set to work.
&lt;/p&gt;
&lt;p&gt;
The result is the &lt;font face="Courier New"&gt;MapperActivity&lt;/font&gt;. The &lt;font face="Courier New"&gt;MapperActivity&lt;/font&gt; requires
you to specify the &lt;font face="Courier New"&gt;SourceType&lt;/font&gt; and &lt;font face="Courier New"&gt;DestinationType&lt;/font&gt; -
we used the &lt;a href="http://www.codeproject.com/KB/cs/WFTypeBrowser.aspx"&gt;Type Browser
from CodeProject&lt;/a&gt; for this. Then you can edit the &lt;font face="Courier New"&gt;Mappings&lt;/font&gt; which
brings up the mapping tool
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WFMapper.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
You drag members (properties or fields) from the left hand side and drop them on type
compatible members (properties or fields) on the right hand side.
&lt;/p&gt;
&lt;p&gt;
Finally you need to databind the &lt;font face="Courier New"&gt;SourceObject&lt;/font&gt; and &lt;font face="Courier New"&gt;DestinationObject&lt;/font&gt;&lt;font face=Verdana&gt; to
tell the mapper where the data comes from and where the data is going&lt;/font&gt;. You
can optionally get the &lt;font face="Courier New"&gt;MapperActivity&lt;/font&gt; to create the
destination object tree if it doesn't exist using the &lt;font face="Courier New"&gt;CanCreateDestination&lt;/font&gt; property.
Here's the full property grid:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/WFMapProps.jpg" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
And&amp;nbsp;thanks to &lt;a href="http://masteringbiztalk.com/blogs/jon/"&gt;Jon Flanders&lt;/a&gt; for
letting me crib his custom &lt;font face="Courier New"&gt;PropertyDescriptor&lt;/font&gt; implementation
(why on earth don't we have a public one in the framework?). You need one of these
when creating extender properties (the &lt;font face="Courier New"&gt;SourceObject&lt;/font&gt; and &lt;font face="Courier New"&gt;DestinationObject&lt;/font&gt; properties
change type based on the &lt;font face="Courier New"&gt;SourceType&lt;/font&gt; and &lt;font face="Courier New"&gt;DestinationType&lt;/font&gt; respectively).
&lt;/p&gt;
&lt;p&gt;
Here is the activity - I'll clean up the code before posting that.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/MapperActivity.zip"&gt;MapperActivity.zip
(37.78 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Feedback always appreciated
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2f6c28f6-dc6e-49e1-afd6-944054c6bd9e" /&gt;</description>
      <category>.NET;BizTalk;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=8584bf84-3ce5-43c5-b43c-377b93258672</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,8584bf84-3ce5-43c5-b43c-377b93258672.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2570b84c-b507-4766-9c9a-c5121eb0f7c6.aspx">last
post</a> I talked about the base class I created for creating custom composites that
you want control over the execution logic. Firstly <a href="http://www.joshlane.net/blog/">Josh</a> pointed
out that I ought to state its limitations - it only executes (and therefore cancels)
one child activity at a time so it would not be useful for building, for example, the <font face="Courier New">ParallelActivity</font>. 
</p>
        <p>
With that limitation in mind though, there are a number of useful applications. I
had a think about a different execution model and came up with prioritized execution.
So I built this on top of my base class which was an interesting exercise as I could
use an attached property for the <font face="Courier New">Priority</font> which meant
I didn't limit the children to a special child activity type. I also had a think about
the design time and realised that the sequential and parallel models for composite
design time wasn't appropriate so I stole^H^H^H^H^H leveraged the designer that the Conditional
Activity Group uses which seemed to work well.
</p>
        <p align="left">
          <img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/CAGDesigner.jpg" border="0" />
        </p>
        <p align="left">
I packaged up the code and told Josh about it
</p>
        <p>
"Oh yeah, thats an interesting one - Dharma Shukla and Bob Schmidt used that in <a href="http://www.amazon.co.uk/Essential-Workflow-Foundation-Microsoft-Development/dp/0321399838/ref=sr_1_2?ie=UTF8&amp;s=books&amp;qid=1196867664&amp;sr=8-2">their
book</a>"
</p>
        <p>
...
</p>
        <p>
It turns out that pretty much half the world has decided to build a prioritised execution
composite. 
</p>
        <p>
Heres the code anyway
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/PrioritizedActivitySample.zip">PrioritizedActivitySample.zip
(76.36 KB)</a>
        </p>
        <p>
But then I got to thinking - actually there is a problem with this approach - elegant
as it may be. If you cannot change the priorities at runtime then all you are building
is an elaborate sequence. So it turns out that attached properties cannot be data
bound in WF - you have to use a full <font face="Courier New">DependencyProperty</font> created
with <font face="Courier New">DependencyProperty.Register</font> rather than <font face="Courier New">DependencyProperty.RegisterAttached</font>.
So I reworked the example, creating a special child activity <font face="Courier New">DynamicPrioritizedSequenceActivity</font> that
has a priority that is a bindable dependency property. I also had to create a validator
to make sure only this type of child could be added to the composite.
</p>
        <p>
This neat thing now is you have a prioritized execution composite whose children
can dynamically change their priority using data binding. The code for this is here
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DynamicPrioritySample.zip">DynamicPrioritySample.zip
(78.83 KB)</a>
        </p>
        <p>
So between these two samples we have prioritized execution, designer support, attached
property support and validator support
</p>
        <p>
As usual all comments welcome
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=8584bf84-3ce5-43c5-b43c-377b93258672" />
      </body>
      <title>Prioritized Execution Composite Sample</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,8584bf84-3ce5-43c5-b43c-377b93258672.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,8584bf84-3ce5-43c5-b43c-377b93258672.aspx</link>
      <pubDate>Wed, 05 Dec 2007 15:47:10 GMT</pubDate>
      <description>&lt;p&gt;
In my &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2570b84c-b507-4766-9c9a-c5121eb0f7c6.aspx"&gt;last
post&lt;/a&gt; I talked about the base class I created for creating custom composites that
you want control over&amp;nbsp;the execution logic. Firstly &lt;a href="http://www.joshlane.net/blog/"&gt;Josh&lt;/a&gt; pointed
out that I ought to state its limitations - it only executes (and therefore cancels)
one child activity at a time so it would not be useful for building, for example,&amp;nbsp;the &lt;font face="Courier New"&gt;ParallelActivity&lt;/font&gt;. 
&lt;/p&gt;
&lt;p&gt;
With that limitation in mind though, there are a number of useful applications. I
had a think about a different execution model and came up with prioritized execution.
So I built this on top of my base class which was an interesting exercise as I could
use an attached property for the &lt;font face="Courier New"&gt;Priority&lt;/font&gt; which meant
I didn't limit the children to a special child activity type. I also had a think about
the design time and realised that the sequential and parallel models for composite
design time wasn't appropriate so I stole^H^H^H^H^H leveraged the designer that the&amp;nbsp;Conditional
Activity Group uses which seemed to work well.
&lt;/p&gt;
&lt;p align=left&gt;
&lt;img src="http://www.dotnetconsult.co.uk/weblog2/content/binary/CAGDesigner.jpg" border=0&gt;
&lt;/p&gt;
&lt;p align=left&gt;
I packaged up the code and told Josh about it
&lt;/p&gt;
&lt;p&gt;
"Oh yeah, thats an interesting one - Dharma Shukla and Bob Schmidt used that in &lt;a href="http://www.amazon.co.uk/Essential-Workflow-Foundation-Microsoft-Development/dp/0321399838/ref=sr_1_2?ie=UTF8&amp;amp;s=books&amp;amp;qid=1196867664&amp;amp;sr=8-2"&gt;their
book&lt;/a&gt;"
&lt;/p&gt;
&lt;p&gt;
...
&lt;/p&gt;
&lt;p&gt;
It turns out that pretty much half the world has decided to build a prioritised execution
composite. 
&lt;/p&gt;
&lt;p&gt;
Heres the code anyway
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/PrioritizedActivitySample.zip"&gt;PrioritizedActivitySample.zip
(76.36 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
But then I got to thinking - actually there is a problem with this approach - elegant
as it may be. If you cannot change the priorities at runtime then all you are building
is an elaborate sequence. So it turns out that attached properties cannot be data
bound in WF - you have to use a full &lt;font face="Courier New"&gt;DependencyProperty&lt;/font&gt; created
with &lt;font face="Courier New"&gt;DependencyProperty.Register&lt;/font&gt; rather than &lt;font face="Courier New"&gt;DependencyProperty.RegisterAttached&lt;/font&gt;.
So I reworked the example, creating a special child activity &lt;font face="Courier New"&gt;DynamicPrioritizedSequenceActivity&lt;/font&gt; that
has a priority that is a bindable dependency property. I also had to create a validator
to make sure only this type of child could be added to the composite.
&lt;/p&gt;
&lt;p&gt;
This neat thing now is you have a prioritized execution composite&amp;nbsp;whose children
can dynamically change their priority using data binding. The code for this is here
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/DynamicPrioritySample.zip"&gt;DynamicPrioritySample.zip
(78.83 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
So between these two samples we have prioritized execution, designer support, attached
property support and validator support
&lt;/p&gt;
&lt;p&gt;
As usual all comments welcome
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=8584bf84-3ce5-43c5-b43c-377b93258672" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=2570b84c-b507-4766-9c9a-c5121eb0f7c6</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2570b84c-b507-4766-9c9a-c5121eb0f7c6.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There are two types of custom composites you may end up writing:
</p>
        <ol>
          <li>
a form of UserControl with a set of activities whose composite functionality you want
to reuse. This is what you get when you add a new activity to a workflow project using
the menu item. You end up with a class that derives from <font face="Courier New">SequenceActivity</font> and
is the one occasion with a custom activity where you don;t really have to override <font face="Courier New">Execute</font></li>
          <li>
a parent that wants to take control over the execution model of its children (think
of the execution model of the <font face="Courier New">IfElseActivity</font>, <font face="Courier New">WhileActivity</font> and
the <font face="Courier New">ParallelActivity</font>)</li>
        </ol>
        <p>
To me the second of these is more interesting (although no doubt less common) and
involves writing a bit of plumbing. In general, though, there is a common pattern
to the code and so I have created a base class that wraps this plumbing. 
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/CustomCompositeBase.zip">CustomCompositeBase.zip
(55.6 KB)</a>
        </p>
        <p>
There are two fundemental overridable methods:
</p>
        <p>
          <font face="Courier New">LastActivityReached</font>: returns whether there are more
child activities to execute<br /><font face="Courier New">GetNextActivity</font>: returns the next activity to be scheduled
</p>
        <p>
Inside the zip there is also a test project that implements a random execution composite
(highly useful I know).
</p>
        <p>
Feedback, as always, very welcome.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2570b84c-b507-4766-9c9a-c5121eb0f7c6" />
      </body>
      <title>Base Class for Custom Composites</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2570b84c-b507-4766-9c9a-c5121eb0f7c6.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,2570b84c-b507-4766-9c9a-c5121eb0f7c6.aspx</link>
      <pubDate>Tue, 04 Dec 2007 09:19:18 GMT</pubDate>
      <description>&lt;p&gt;
There are two types of custom composites you may end up writing:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
a form of UserControl with a set of activities whose composite functionality you want
to reuse. This is what you get when you add a new activity to a workflow project using
the menu item. You end up with a class that derives from &lt;font face="Courier New"&gt;SequenceActivity&lt;/font&gt; and
is the one occasion with a custom activity where you don;t really have to override &lt;font face="Courier New"&gt;Execute&lt;/font&gt; 
&lt;li&gt;
a parent that wants to take control over the execution model of its children (think
of the execution model of the &lt;font face="Courier New"&gt;IfElseActivity&lt;/font&gt;, &lt;font face="Courier New"&gt;WhileActivity&lt;/font&gt; and
the &lt;font face="Courier New"&gt;ParallelActivity&lt;/font&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
To me the second of these is more interesting (although no doubt less common) and
involves writing a bit of plumbing. In general, though,&amp;nbsp;there is a common pattern
to the code and so I have created a base class that wraps this plumbing. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/CustomCompositeBase.zip"&gt;CustomCompositeBase.zip
(55.6 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
There are two fundemental overridable methods:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;LastActivityReached&lt;/font&gt;: returns whether there are more
child activities to execute&lt;br&gt;
&lt;font face="Courier New"&gt;GetNextActivity&lt;/font&gt;: returns the next activity to be scheduled
&lt;/p&gt;
&lt;p&gt;
Inside the zip there is also a test project that implements a random execution composite
(highly useful I know).
&lt;/p&gt;
&lt;p&gt;
Feedback, as always, very welcome.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=2570b84c-b507-4766-9c9a-c5121eb0f7c6" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=abe40cae-d1ad-44d5-843a-b1b3b7aec9d7</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,abe40cae-d1ad-44d5-843a-b1b3b7aec9d7.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yesterday I <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx">posted</a> a
base class for Async Activities that buried all the plumbing. However, looking at
the zip I only had the binary for the base class and the test harness. Here is the
zipped code.
</p>
        <p>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass12.zip">AsyncActivityBaseClass12.zip
(69.71 KB)</a>
          <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass1.zip">
          </a>
        </p>
        <p>
In addition <a href="http://www.develop.com/technology/bio.aspx?id=105">Rod</a> gave
me some feedback (for example making the base class abstract messed up the design
time view for the derived activity). In the light of that and other ideas I have made
some changes:
</p>
        <ul>
          <li>
The base class is now concrete and so designer view now works for derived classes 
</li>
          <li>
If you don't supply a queue name then the queue name defaults to the <font face="Courier New">QualifiedName</font> of
the activity 
</li>
          <li>
Cancellation support is now embedded in the base class. 
</li>
          <li>
There is a new override called <font face="Courier New">DoAsyncTeardown</font> to
allow you to deallocate any resources you allocated in <font face="Courier New">DoAsyncSetup</font></li>
        </ul>
        <p>
I hope someone finds this useful
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=abe40cae-d1ad-44d5-843a-b1b3b7aec9d7" />
      </body>
      <title>Async Activity Helper - Redux</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,abe40cae-d1ad-44d5-843a-b1b3b7aec9d7.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,abe40cae-d1ad-44d5-843a-b1b3b7aec9d7.aspx</link>
      <pubDate>Sun, 02 Dec 2007 12:19:15 GMT</pubDate>
      <description>&lt;p&gt;
Yesterday I &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx"&gt;posted&lt;/a&gt; a
base class for Async Activities that buried all the plumbing. However, looking at
the zip I only had the binary for the base class and the test harness. Here is the
zipped code.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass12.zip"&gt;AsyncActivityBaseClass12.zip
(69.71 KB)&lt;/a&gt;&lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass1.zip"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
In addition &lt;a href="http://www.develop.com/technology/bio.aspx?id=105"&gt;Rod&lt;/a&gt; gave
me some feedback (for example making the base class abstract messed up the design
time view for the derived activity). In the light of that and other ideas I have made
some changes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The base class is now concrete and so designer view now works for derived classes 
&lt;li&gt;
If you don't supply a queue name then the queue name defaults to the &lt;font face="Courier New"&gt;QualifiedName&lt;/font&gt; of
the activity 
&lt;li&gt;
Cancellation support is now embedded in the base class. 
&lt;li&gt;
There is a new override called &lt;font face="Courier New"&gt;DoAsyncTeardown&lt;/font&gt; to
allow you to deallocate any resources you allocated in &lt;font face="Courier New"&gt;DoAsyncSetup&lt;/font&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I hope someone finds this useful
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=abe40cae-d1ad-44d5-843a-b1b3b7aec9d7" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=57c15a22-0c71-480c-9118-309a896adcde</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the most powerful aspects of Windows Workflow is that it can manage a workflow
instance's state when it has no work to do. Obviously to do this it needs to know
that your activity is waiting for something to happen. A number of activities in the
Standard Activity Library run asynchronously like this -e.g. the <font face="Courier New">DelayActivity</font> and
the new <font face="Courier New">ReceiveActivity</font>. However, most real WF projects
require you to write your own custom activities. To perform long running operations
or wait for external events to occur, these too should be able to run asynchronously. 
</p>
        <p>
To be usable in all situations, an async activity needs to do more than just derive
from <font face="Courier New">Activity</font> and return <font face="Courier New">ActivityExecutionStatus.Executing</font><font face="Verdana"> from
the <font face="Courier New">Execute</font> override</font>. It also needs to implement <font face="Courier New">IActivityEventListener&lt;QueueEventArgs&gt;</font> and <font face="Courier New">IEventActivity</font> (the
latter allows it to be recognised as an event driven activity). We end up with 3 interesting
methods
</p>
        <p>
          <font face="Courier New">Execute<br />
IEventActivity.Subscribe<br />
IEventActivity.Unsubscribe</font>
        </p>
        <p>
Depending where your activity is used these get called in a different order
</p>
        <p>
Sequential Workflow: Execute<br />
State Machine: Subscribe, Execute, Unsubscribe<br />
ListenActivity: Subscribe, Unsubscribe, Execute
</p>
        <p>
So getting the behavior correct in where you create the workflow queue you are going
to listen on, set up the event handler on the queue, process the results from the
queue and close the activity can be a little tricky. So I have created a base class
for async activities that buries the complexity of the plumbing and leaves you with
three responsiblities:
</p>
        <ol>
          <li>
Tell the base class the name of the queue you wish to wait on 
</li>
          <li>
Optionally override a method to set up any infrastructure you need before you start
waiting on the queue 
</li>
          <li>
Override a method to process the data that was passed on to the queue and decide whether
you are still waiting for more data or you are finished</li>
        </ol>
        <p>
You can download the code here <a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass.zip">AsyncActivityBaseClass.zip
(38.36 KB)</a>. Any feedback gratefully received
</p>
        <p>
Finally, thanks to <a href="http://www.joshlane.net/blog/">Josh</a> and <a href="http://blogs.thinktecture.com/cweyer/">Christian</a> for
sanity checking the code
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=57c15a22-0c71-480c-9118-309a896adcde" />
      </body>
      <title>Async Activity Helper</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,57c15a22-0c71-480c-9118-309a896adcde.aspx</link>
      <pubDate>Sat, 01 Dec 2007 08:17:49 GMT</pubDate>
      <description>&lt;p&gt;
One of the most powerful aspects of Windows Workflow is that it can manage a workflow
instance's state when it has no work to do. Obviously to do this it needs to know
that your activity is waiting for something to happen. A number of activities in the
Standard Activity Library run asynchronously like this -e.g. the &lt;font face="Courier New"&gt;DelayActivity&lt;/font&gt; and
the new &lt;font face="Courier New"&gt;ReceiveActivity&lt;/font&gt;. However, most real WF projects
require you to write your own custom activities. To perform long running operations
or wait for external events to occur, these too should be able to run asynchronously. 
&lt;/p&gt;
&lt;p&gt;
To be usable in all situations, an async activity needs to do more than just derive
from &lt;font face="Courier New"&gt;Activity&lt;/font&gt; and return &lt;font face="Courier New"&gt;ActivityExecutionStatus.Executing&lt;/font&gt;&lt;font face=Verdana&gt; from
the &lt;font face="Courier New"&gt;Execute&lt;/font&gt; override&lt;/font&gt;. It also needs to implement &lt;font face="Courier New"&gt;IActivityEventListener&amp;lt;QueueEventArgs&amp;gt;&lt;/font&gt; and &lt;font face="Courier New"&gt;IEventActivity&lt;/font&gt; (the
latter allows it to be recognised as an event driven activity). We end up with 3 interesting
methods
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;Execute&lt;br&gt;
IEventActivity.Subscribe&lt;br&gt;
IEventActivity.Unsubscribe&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Depending where your activity is used these get called in a different order
&lt;/p&gt;
&lt;p&gt;
Sequential Workflow: Execute&lt;br&gt;
State Machine: Subscribe, Execute, Unsubscribe&lt;br&gt;
ListenActivity: Subscribe, Unsubscribe, Execute
&lt;/p&gt;
&lt;p&gt;
So getting the behavior correct in where you create the workflow queue you are going
to listen on, set up the event handler on the queue, process the results from the
queue and close the activity can be a little tricky. So I have created a base class
for async activities that buries the complexity of the plumbing and leaves you with
three responsiblities:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Tell the base class the name of the queue you wish to wait on 
&lt;li&gt;
Optionally override a method to set up any infrastructure you need before you start
waiting on the queue 
&lt;li&gt;
Override a method to process the data that was passed on to the queue and decide whether
you are still waiting for more data or you are finished&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
You can download the code here &lt;a href="http://www.dotnetconsult.co.uk/weblog2/content/binary/AsyncActivityBaseClass.zip"&gt;AsyncActivityBaseClass.zip
(38.36 KB)&lt;/a&gt;.&amp;nbsp;Any feedback gratefully received
&lt;/p&gt;
&lt;p&gt;
Finally, thanks to &lt;a href="http://www.joshlane.net/blog/"&gt;Josh&lt;/a&gt; and &lt;a href="http://blogs.thinktecture.com/cweyer/"&gt;Christian&lt;/a&gt; for
sanity checking the code
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=57c15a22-0c71-480c-9118-309a896adcde" /&gt;</description>
      <category>.NET;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=77c334e8-0ec1-4f91-ab7e-0bcfa7f2f47d</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,77c334e8-0ec1-4f91-ab7e-0bcfa7f2f47d.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the <a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f3237d63-209e-4355-b8db-ef5574d34c18.aspx">previous
article</a> I talked about hosting options for WCF. Here I'll discuss hosting for
WF. However, to understand the options fully we need to digress briefly and talk about
some of the features of WF.
</p>
        <h5>Asynchronous Execution
</h5>
        <p>
The execution model of WF is inherently asynchronous. Activities are queued up for
execution and the runtime asks the scheduler service to make the calls to <font face="Courier New">Activity.Execute</font> on
to threads. The <font face="Courier New">DefaultWorkflowSchedulerService</font> (which
you get if you take no special actions) maps <font face="Courier New">Execute</font> calls
on to thread pool worker threads. The <font face="Courier New">ManualWorkflowSchedulerService</font> (which
also comes out of the box but you have to install specifically install using WorkflowRuntime.AddService)
schedules <font face="Courier New">Execute</font> on the thread that calls <font face="Courier New">ManualWorkflowSchedulerService.RunWorkflow</font>.
</p>
        <h5>Persistence
</h5>
        <p>
By default the workflow runtime does not persist workflows. Only when an object of
a type that derives from <font face="Courier New">WorkflowPersistenceService</font> is
added as a runtime service does the workflow runtime start persisting workflows both
in the form of checkpoints when significant things have happened in the workflow's
execution and to unload a workflow when it goes idle. When something happens that
should be directed to an unloaded workflow the host (or a service) calls <font face="Courier New">WorkflowRuntime.GetWorkflow(instanceId)</font> and
the runtime can reload the workflow from persistent storage. 
</p>
        <p>
One issue here is that of timers. If a workflow has gone idle waiting for a timer
to expire (say via the <font face="Courier New">DelayActivity</font>) then no external
event is going to occur to trigger a call <font face="Courier New">WorkflowRuntime.GetWorkflow(instanceId)</font><font face="Verdana">to
allow the workflow to continue execution. In this case the persistence service must
have functionality to discover when a timer has expired in a persisted workflow. The
out of the box implementation, the <font face="Courier New">SqlWorkflowPersistenceService</font> polls
the database periodically (how often is controlled by a parameter passed to its constructor).
Obviously for this to occur the workflow runtime has to be loaded and running (via <font face="Courier New">WorkflowRuntime.StartRuntime</font>).</font></p>
        <h5>Hosting Options
</h5>
        <p>
The above two issues affect your WF hosting decisions and implementation. As with
WCF you can host in any .NET process but in many ways the responsibilities of a WF
host are more far reaching than for a WCF host. Essentially a WCF host has to start
listening on the endpoints for the services it is hosting. A WF host not only has
to configure and start the workflow runtime but also decide when new workflow instances
should be created and broker communication from the outside world into the workflow.
So lets look at the various options.
</p>
        <h5>WF Console Hosting
</h5>
        <p>
When you install the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=5D61409E-1FA3-48CF-8023-E8F38E709BA6&amp;displaylang=en"><em>Visual
Studio 2005 Extensions for Windows Workflow Foundation</em> package</a> you get new
project types which include console projects for both sequential and state machine
workflows. These project types are useful for doing research and demos but thats about
it.
</p>
        <h5>WF Smart Client Hosting
</h5>
        <p>
There are a number of WF features that make it desirable to host WF in a smart client.
Among these are the ability to control complex page navigation and the WF rules engine
for controlling complex cross field navigation. The <a href="http://windowsclient.net/Acropolis/">Acropolis</a> team
are planning to provide WF based navigation in their framework.
</p>
        <h5>WF ASP.NET Hosting
</h5>
        <p>
One of the common use cases of WF hosting is controlling page flow in ASP.NET
applications. This isn't by any means the sum total of application of WF in ASP.NET;
for example, the website may be the gateway into starting and monitoring long running
business processes. There are two main issues with ASP.NET hosting:
</p>
        <ol>
          <li>
ASP.NET runs executes on thread pool worker threads as does the <font face="Courier New">DefaultWorkflowSchedulerService</font>.
ASP.NET also stores the <font face="Courier New">HttpContext</font> in thread local
storage. So if the workflow invokes functionality that requires access to <font face="Courier New">HttpContext</font> or
the ASP.NET request needs to wait for the workflow then you should use the <font face="Courier New">ManualWorkflowSchedulerService</font> as
the scheduler. This also means that the workflow runtime and ASP.Net will not be competing
for threads. 
</li>
          <li>
For long running workflows the workflow will probably be persisted and so the persistence
service needs to recognise when timeouts have occurred. However, to do this the workflow
runtime needs to be executing. So why is this an issue? Well in ASP.NET hosting the
lifetime of the workflow runtime is generally tied to that of the <font face="Courier New">Application</font> object
and therefore to the lifetime of the hosting AppDomain. But ASP.NET does AppDomain
and worker process recycling - the AppDomain not being recreated until the next request.
Therefore, if no requests come in (maybe the site has bursts of activity then periods
of inactivity) the AppDomain may be recycled and the workflow runtime stop executing.
At this point the persistence service can no longer recognise when timers have expired.</li>
        </ol>
        <p>
As long as your workflows do not require persistence or you have (or can create via
a sentinel process) a regular stream of requests then ASP.NET is an excellent workflow
host - especially if IIS is being used to host WCF endpoints that hand off to
workflows. just remember it is not suitable for all applications.
</p>
        <h5>WF Windows Service Hosting
</h5>
        <p>
A Windows Service is the most flexible host for WF as the workflow runtime lifetime
is generally tied to the lifetime of the process. Obviously, you will probably have
to write a communication layer to allow the workflows to be contacted by the outside
world. In places where ASP.NET isn't a suitable host it can delegate to a Windows
Service based host. Just remember there is an overhead to hand off to the windows
service from another process (say via WCF using the netNamedPipeBinding) so make sure
ASP.NET really isn't suitable before you go down this path.
</p>
        <p>
WF is a powerful tool for many applications and the host plays a crucial role in providing
the right environment for WF execution. Hopefully this article has given some insight
into use cases and issues with the various hosting options.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=77c334e8-0ec1-4f91-ab7e-0bcfa7f2f47d" />
      </body>
      <title>WF Hosting Options</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,77c334e8-0ec1-4f91-ab7e-0bcfa7f2f47d.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,77c334e8-0ec1-4f91-ab7e-0bcfa7f2f47d.aspx</link>
      <pubDate>Thu, 07 Jun 2007 12:39:04 GMT</pubDate>
      <description>&lt;p&gt;
In the &lt;a href="http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f3237d63-209e-4355-b8db-ef5574d34c18.aspx"&gt;previous
article&lt;/a&gt; I talked about hosting options for WCF. Here I'll discuss hosting for
WF. However, to understand the options fully we need to digress briefly and talk about
some of the features of WF.
&lt;/p&gt;
&lt;h5&gt;Asynchronous Execution
&lt;/h5&gt;
&lt;p&gt;
The execution model of WF is inherently asynchronous. Activities are queued up for
execution and the runtime asks the scheduler service to make the calls to &lt;font face="Courier New"&gt;Activity.Execute&lt;/font&gt; on
to threads. The &lt;font face="Courier New"&gt;DefaultWorkflowSchedulerService&lt;/font&gt; (which
you get if you take no special actions) maps &lt;font face="Courier New"&gt;Execute&lt;/font&gt; calls
on to thread pool worker threads. The &lt;font face="Courier New"&gt;ManualWorkflowSchedulerService&lt;/font&gt; (which
also comes out of the box but you have to install specifically install using WorkflowRuntime.AddService)
schedules &lt;font face="Courier New"&gt;Execute&lt;/font&gt; on the thread that calls &lt;font face="Courier New"&gt;ManualWorkflowSchedulerService.RunWorkflow&lt;/font&gt;.
&lt;/p&gt;
&lt;h5&gt;Persistence
&lt;/h5&gt;
&lt;p&gt;
By default the workflow runtime does not persist workflows. Only when an object of
a type that derives from &lt;font face="Courier New"&gt;WorkflowPersistenceService&lt;/font&gt; is
added as a runtime service does the workflow runtime start persisting workflows both
in the form of checkpoints when significant things have happened in the workflow's
execution and to unload a workflow when it goes idle. When something happens that
should be directed to an unloaded workflow the host (or a service) calls &lt;font face="Courier New"&gt;WorkflowRuntime.GetWorkflow(instanceId)&lt;/font&gt; and
the runtime can reload the workflow from persistent storage. 
&lt;/p&gt;
&lt;p&gt;
One issue here is that of timers. If a workflow has gone idle waiting for a timer
to expire (say via the &lt;font face="Courier New"&gt;DelayActivity&lt;/font&gt;) then no external
event is going to occur to trigger a call &lt;font face="Courier New"&gt;WorkflowRuntime.GetWorkflow(instanceId)&lt;/font&gt;&lt;font face=Verdana&gt;to
allow the workflow to continue execution. In this case the persistence service must
have functionality to discover when a timer has expired in a persisted workflow. The
out of the box implementation, the &lt;font face="Courier New"&gt;SqlWorkflowPersistenceService&lt;/font&gt; polls
the database periodically (how often is controlled by a parameter passed to its constructor).
Obviously for this to occur the workflow runtime has to be loaded and running (via &lt;font face="Courier New"&gt;WorkflowRuntime.StartRuntime&lt;/font&gt;).&lt;/font&gt;
&lt;/p&gt;
&lt;h5&gt;Hosting Options
&lt;/h5&gt;
&lt;p&gt;
The above two issues affect your WF hosting decisions and implementation. As with
WCF you can host in any .NET process but in many ways the responsibilities of a WF
host are more far reaching than for a WCF host. Essentially a WCF host has to start
listening on the endpoints for the services it is hosting. A WF host not only has
to configure and start the workflow runtime but also decide when new workflow instances
should be created and broker communication from the outside world into the workflow.
So lets look at the various options.
&lt;/p&gt;
&lt;h5&gt;WF Console Hosting
&lt;/h5&gt;
&lt;p&gt;
When you install the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=5D61409E-1FA3-48CF-8023-E8F38E709BA6&amp;amp;displaylang=en"&gt;&lt;em&gt;Visual
Studio 2005 Extensions for Windows Workflow Foundation&lt;/em&gt; package&lt;/a&gt; you get new
project types which include console projects for both sequential and state machine
workflows. These project types are useful for doing research and demos but thats about
it.
&lt;/p&gt;
&lt;h5&gt;WF Smart Client Hosting
&lt;/h5&gt;
&lt;p&gt;
There are a number of WF features that make it desirable to host WF in a smart client.
Among these are the ability to control complex page navigation and the WF rules engine
for controlling complex cross field navigation. The &lt;a href="http://windowsclient.net/Acropolis/"&gt;Acropolis&lt;/a&gt; team
are planning to provide WF based navigation in their framework.
&lt;/p&gt;
&lt;h5&gt;WF ASP.NET Hosting
&lt;/h5&gt;
&lt;p&gt;
One of the&amp;nbsp;common use cases of WF hosting is controlling page flow in ASP.NET
applications. This isn't by any means the sum total of application of WF in ASP.NET;
for example, the website may be the gateway into starting and monitoring long running
business processes. There are two main issues with ASP.NET hosting:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
ASP.NET runs executes on thread pool worker threads as does the &lt;font face="Courier New"&gt;DefaultWorkflowSchedulerService&lt;/font&gt;.
ASP.NET also stores the &lt;font face="Courier New"&gt;HttpContext&lt;/font&gt; in thread local
storage. So if&amp;nbsp;the&amp;nbsp;workflow invokes functionality that requires access to &lt;font face="Courier New"&gt;HttpContext&lt;/font&gt; or
the ASP.NET request needs to wait for the workflow then you should use the &lt;font face="Courier New"&gt;ManualWorkflowSchedulerService&lt;/font&gt; as
the scheduler. This also means that the workflow runtime and ASP.Net will not be competing
for threads. 
&lt;li&gt;
For long running workflows the workflow will probably be persisted and so the persistence
service needs to recognise when timeouts have occurred. However, to do this the workflow
runtime needs to be executing. So why is this an issue? Well in ASP.NET hosting the
lifetime of the workflow runtime is generally tied to that of the &lt;font face="Courier New"&gt;Application&lt;/font&gt; object
and therefore to the lifetime of the hosting AppDomain. But ASP.NET does AppDomain
and worker process recycling - the AppDomain not being recreated until the next request.
Therefore, if no requests come in (maybe the site has bursts of activity then periods
of inactivity) the AppDomain may be recycled and the workflow runtime stop executing.
At this point the persistence service can no longer recognise when timers have expired.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
As long as your workflows do not require persistence or you have (or can create via
a sentinel process) a regular stream of requests then ASP.NET is an excellent workflow
host - especially if&amp;nbsp;IIS is being used to host WCF endpoints that hand off to
workflows. just remember it is not suitable for all applications.
&lt;/p&gt;
&lt;h5&gt;WF Windows Service Hosting
&lt;/h5&gt;
&lt;p&gt;
A Windows Service is the most flexible host for WF as the workflow runtime lifetime
is generally tied to the lifetime of the process. Obviously, you will probably have
to write a communication layer to allow the workflows to be contacted by the outside
world.&amp;nbsp;In places where ASP.NET isn't a suitable host it can delegate to a Windows
Service based host. Just remember there is an overhead to hand off to the windows
service from another process (say via WCF using the netNamedPipeBinding) so make sure
ASP.NET really isn't suitable before you go down this path.
&lt;/p&gt;
&lt;p&gt;
WF is a powerful tool for many applications and the host plays a crucial role in providing
the right environment for WF execution. Hopefully this article has given some insight
into use cases and issues with the various hosting options.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=77c334e8-0ec1-4f91-ab7e-0bcfa7f2f47d" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=c27fc8a1-342f-46c1-b7cd-2ed4f7c4a7a5</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c27fc8a1-342f-46c1-b7cd-2ed4f7c4a7a5.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have just uploaded the code from mine and <a href="http://www.masteringbiztalk.com">Jon's</a> precon
on WCF and WF. You can download it <a href="techedcode.zip">here</a>.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c27fc8a1-342f-46c1-b7cd-2ed4f7c4a7a5" />
      </body>
      <title>TechEd 2007 Precon Code</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c27fc8a1-342f-46c1-b7cd-2ed4f7c4a7a5.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,c27fc8a1-342f-46c1-b7cd-2ed4f7c4a7a5.aspx</link>
      <pubDate>Thu, 07 Jun 2007 03:26:21 GMT</pubDate>
      <description>&lt;p&gt;
I have just uploaded the code from mine and &lt;a href="http://www.masteringbiztalk.com"&gt;Jon's&lt;/a&gt; precon
on WCF and WF. You can download it &lt;a href="techedcode.zip"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=c27fc8a1-342f-46c1-b7cd-2ed4f7c4a7a5" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=f3237d63-209e-4355-b8db-ef5574d34c18</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f3237d63-209e-4355-b8db-ef5574d34c18.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
WCF and WF are both frameworks. Specifically this means they are not full blown products
but rather blocks of utility code with which to build products. For both of these
frameworks the hosting process is undefined and it is up to you to provide this. As
.NET based frameworks the host can be any .NET process so what are the advantages
and disadvantages of each? In this the first of two articles I'll look at options
and issues hosting WCF then in the next article I'll do the same for WF.
</p>
        <h5>WCF Console Hosting
</h5>
        <p>
Console apps are useful for testing things out and can be useful for mocking up a
service if you are testing a client. However, they are not suitable for production
systems as they have no resilience associated with them.
</p>
        <h5>WCF Smart Client Hosting
</h5>
        <p>
Useful for peer to peer applications.
</p>
        <h5>WCF Windows Service Hosting
</h5>
        <p>
This is a tangible host for  production services. Whether this is the best host
depends on a number of questions:
</p>
        <ul>
          <li>
What operation system am I running on? 
</li>
          <li>
What network protocols do I need to support? 
</li>
          <li>
Do I need to execute any code <em>before</em> the first request comes in?</li>
        </ul>
        <p>
Assuming you want to run this on a server OS and one that is currently released you
will have to use Windows Server 2003 (.NET 3.0 isn't supported on Windows 2000 or
earlier). If you want to use any protocol other HTTP or you need to execute code
before the first request comes in you must use a Windows Service to host your WCF
service.
</p>
        <p>
If you are happy to run on Vista or Windows Server 2008 Beta (formally known as Longhorn
Server) then you should only use a Windows Service if you need to execute code before
the first request arrives.
</p>
        <h5>WCF IIS Hosting
</h5>
        <p>
IIS should be your host of choice for WCF services. However, there are two issues
to be aware of:
</p>
        <ol>
          <li>
IIS6 and earlier can only host services that use HTTP as a transport. IIS7 introduces
the Windows Process Activation Service that allows arbitrary protocols (such as TCP
and MSMQ) to have the same activation facilities as HTTP.</li>
          <li>
IIS provides activation on the first request. If you need to execute code before this
(for example if you have a service that records trend data over time for some external
data source and your service queries this trend data) then you cannot use IIS as a
host without adding out of band infrastructure to bootstrap the application by performing
a request.</li>
        </ol>
        <p>
So the options for WCF hosting are pretty straightforward. In the next article we'll
see that the hosting options for WF have some issues that may not at first be obvious.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=f3237d63-209e-4355-b8db-ef5574d34c18" />
      </body>
      <title>WCF Hosting Options</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f3237d63-209e-4355-b8db-ef5574d34c18.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,f3237d63-209e-4355-b8db-ef5574d34c18.aspx</link>
      <pubDate>Wed, 06 Jun 2007 21:36:24 GMT</pubDate>
      <description>&lt;p&gt;
WCF and WF are both frameworks. Specifically this means they are not full blown products
but rather blocks of utility code with which to build products. For both of these
frameworks the hosting process is undefined and it is up to you to provide this. As
.NET based frameworks the host can be any .NET process so what are the advantages
and disadvantages of each? In this the first of two articles I'll look at options
and issues hosting WCF then in the next article I'll do the same for WF.
&lt;/p&gt;
&lt;h5&gt;WCF Console Hosting
&lt;/h5&gt;
&lt;p&gt;
Console apps are useful for testing things out and can be useful for mocking up a
service if you are testing a client. However, they are not suitable for production
systems as they have no resilience associated with them.
&lt;/p&gt;
&lt;h5&gt;WCF Smart Client Hosting
&lt;/h5&gt;
&lt;p&gt;
Useful for peer to peer applications.
&lt;/p&gt;
&lt;h5&gt;WCF Windows Service Hosting
&lt;/h5&gt;
&lt;p&gt;
This is a tangible host for &amp;nbsp;production services. Whether this is the best host
depends on a number of questions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
What operation system am I running on? 
&lt;li&gt;
What network protocols do I need to support? 
&lt;li&gt;
Do I need to execute any code &lt;em&gt;before&lt;/em&gt; the first request comes in?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Assuming you want to run this on a server OS and one that is currently released you
will have to use Windows Server 2003 (.NET 3.0 isn't supported on Windows 2000 or
earlier). If you&amp;nbsp;want to use any protocol other HTTP or you need to execute code
before the first request comes in you must use a Windows Service to host your WCF
service.
&lt;/p&gt;
&lt;p&gt;
If you are happy to run on Vista or Windows Server 2008 Beta (formally known as Longhorn
Server) then you should only use a Windows Service if you need to execute code before
the first request arrives.
&lt;/p&gt;
&lt;h5&gt;WCF IIS Hosting
&lt;/h5&gt;
&lt;p&gt;
IIS should be your host of choice for WCF services. However, there are two issues
to be aware of:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
IIS6 and earlier can only host services that use HTTP as a transport. IIS7 introduces
the Windows Process Activation Service that allows arbitrary protocols (such as TCP
and MSMQ) to have the same activation facilities as HTTP.&lt;/li&gt;
&lt;li&gt;
IIS provides activation on the first request. If you need to execute code before this
(for example if you have a service that records trend data over time for some external
data source and your service queries this trend data) then you cannot use IIS as a
host without adding out of band infrastructure to bootstrap the application by performing
a request.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
So the options for WCF hosting are pretty straightforward. In the next article we'll
see that the hosting options for WF have some issues that may not at first be obvious.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=f3237d63-209e-4355-b8db-ef5574d34c18" /&gt;</description>
      <category>.NET;WCF;WF</category>
    </item>
    <item>
      <trackback:ping>http://www.dotnetconsult.co.uk/weblog2/Trackback.aspx?guid=ee213dd2-3a37-4469-b942-c73cf02b684f</trackback:ping>
      <pingback:server>http://www.dotnetconsult.co.uk/weblog2/pingback.aspx</pingback:server>
      <pingback:target>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ee213dd2-3a37-4469-b942-c73cf02b684f.aspx</pingback:target>
      <dc:creator>Richard Blewett</dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Just sitting in on a session on extending the WF rules infrastructure given by <a href="http://blogs.msdn.com/moustafa/">Moustafa
Ahmed</a>. Some interesting ideas. I especially liked the infrastructure for decoupling
the rules from the workflow assembly using a repository, custom workflow service and
a custom policy activity. He also showed a custom rules editor that was business user
friendly (which the OOB one isn't) called <a href="http://www.inrule.com/">inrule</a> which
looked pretty good.
</p>
        <img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ee213dd2-3a37-4469-b942-c73cf02b684f" />
      </body>
      <title>TechEd and WF Rules</title>
      <guid isPermaLink="false">http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ee213dd2-3a37-4469-b942-c73cf02b684f.aspx</guid>
      <link>http://www.dotnetconsult.co.uk/weblog2/PermaLink,guid,ee213dd2-3a37-4469-b942-c73cf02b684f.aspx</link>
      <pubDate>Wed, 06 Jun 2007 19:05:31 GMT</pubDate>
      <description>&lt;p&gt;
Just sitting in on a session on extending the WF rules infrastructure given by &lt;a href="http://blogs.msdn.com/moustafa/"&gt;Moustafa
Ahmed&lt;/a&gt;. Some interesting ideas. I especially liked the infrastructure for decoupling
the rules from the workflow assembly using a repository, custom workflow service and
a custom policy activity. He also showed a custom rules editor that was business user
friendly (which the OOB one isn't) called &lt;a href="http://www.inrule.com/"&gt;inrule&lt;/a&gt; which
looked pretty good.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.dotnetconsult.co.uk/weblog2/aggbug.ashx?id=ee213dd2-3a37-4469-b942-c73cf02b684f" /&gt;</description>
      <category>.NET;WF</category>
    </item>
  </channel>
</rss>