<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://community.bartdesmet.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>B# .NET Blog : .NET Framework 3.0 (WinFX)</title><link>http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx</link><description>Tags: .NET Framework 3.0 (WinFX)</description><dc:language>en</dc:language><generator>CommunityServer 2007 (Build: 20423.869)</generator><item><title>.NET Framework Library Source Code now available</title><link>http://community.bartdesmet.net/blogs/bart/archive/2008/01/16/net-framework-library-source-code-now-available.aspx</link><pubDate>Thu, 17 Jan 2008 01:30:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12964</guid><dc:creator>bart</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12964</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2008/01/16/net-framework-library-source-code-now-available.aspx#comments</comments><description>&lt;p&gt;That&amp;#39;s right - we&amp;#39;ve published the .NET Framework Library Source Code to the public. Scott Guthrie has the &lt;a class="" href="http://weblogs.asp.net/scottgu/archive/2008/01/16/net-framework-library-source-code-now-available.aspx"&gt;full details&lt;/a&gt;. Getting the sources out for the WPF team has been one of my first jobs on the team, which was an interesting experience crawling through the source tree, finding out about build system stuff, and so much more. In technical terms, you now have access to the PDB files over HTTP, as outlined by Shawn Burke &lt;a class="" href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx"&gt;over here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Anyway, enjoy debugging through the BCL sources!&lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12964" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Presentation+Foundation+_2800_WPF_2900_/default.aspx">Windows Presentation Foundation (WPF)</category></item><item><title>WF - Hello World via the Command Line (wfc.exe explained)</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/12/07/WF-_2D00_-Hello-World-via-the-Command-Line.aspx</link><pubDate>Thu, 07 Dec 2006 22:08:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:12029</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=12029</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/12/07/WF-_2D00_-Hello-World-via-the-Command-Line.aspx#comments</comments><description>&lt;h1&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Introduction&lt;/font&gt;&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;A reader of mine noticed I&amp;#39;m using Visual Studio 2005 as the tool to create all of my Windows Workflow Foundation related samples, instead of taking my favorite minimal command-line approach to create basic samples. So here it is today: a simple Hello World demo of WF using the command-line.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h1&gt;&lt;font color="#000080"&gt;Please welcome WFC&lt;/font&gt;&lt;/h1&gt;&lt;p&gt;Just like csc.exe is the C#&amp;#39;s programmer best friend, wfc.exe plays that role for WF programmers. Basically it turns a .xoml file (which stands for eXtensible Object Markup Language) into a .dll assembly file representing the workflow you&amp;#39;ve designed. Below you can see a simple demo.xoml file:&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;lt;&lt;font color="#800000"&gt;SequentialWorkflowActivity&lt;/font&gt; &lt;font color="#ff0000"&gt;x:Name&lt;/font&gt;=&amp;quot;Demo&amp;quot; &lt;font color="#ff0000"&gt;x:Class&lt;/font&gt;=&amp;quot;FooBar.Demo&amp;quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;font color="#ff0000"&gt;xmlns:x&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml/workflow&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/winfx/2006/xaml/workflow&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;CodeActivity&lt;/font&gt; &lt;font color="#ff0000"&gt;x:Name&lt;/font&gt;=&amp;quot;sayHello&amp;quot; &lt;font color="#ff0000"&gt;ExecuteCode&lt;/font&gt;=&amp;quot;sayHello_ExecuteCode&amp;quot;&lt;font face="courier new"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;x:Code&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;![CDATA[&lt;br /&gt;&lt;font color="#808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void sayHello_ExecuteCode(object sender, EventArgs e) &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; {&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; Console.WriteLine(&amp;quot;Hello World&amp;quot;);&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; }&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]]&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;x:Code&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;CodeActivity&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;font color="#800000"&gt;SequentialWorkflowActivity&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;This simple sample can be compiled into a .dll file by invoking the following:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;gt;wfc demo.xoml&lt;/font&gt;&lt;/p&gt;&lt;p&gt;In this case, we&amp;#39;ve been using a CDATA section to put the code inline between the XOML definition. Another approach would be to put the following in the demo.xoml file:&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;lt;&lt;font color="#800000"&gt;SequentialWorkflowActivity&lt;/font&gt; &lt;font color="#ff0000"&gt;x:Name&lt;/font&gt;=&amp;quot;Demo&amp;quot; &lt;font color="#ff0000"&gt;x:Class&lt;/font&gt;=&amp;quot;FooBar.Demo&amp;quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;font color="#ff0000"&gt;xmlns:x&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml/workflow&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/winfx/2006/xaml/workflow&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;CodeActivity&lt;/font&gt; &lt;font color="#ff0000"&gt;x:Name&lt;/font&gt;=&amp;quot;sayHello&amp;quot; &lt;font color="#ff0000"&gt;ExecuteCode&lt;/font&gt;=&amp;quot;sayHello_ExecuteCode&amp;quot; /&lt;font face="courier new"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;lt;/&lt;font color="#800000"&gt;SequentialWorkflowActivity&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;and to create another file called demo.cs:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;System; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;namespace&lt;/font&gt; FooBar&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;partial class &lt;/font&gt;Demo&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;void&lt;/font&gt; sayHello_ExecuteCode(&lt;font color="#0000ff"&gt;object&lt;/font&gt; sender, &lt;font color="#008080"&gt;EventArgs&lt;/font&gt; e) &lt;br /&gt;&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; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(&lt;font color="#800000"&gt;&amp;quot;Hello World&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;&lt;p&gt;which can be compiled using:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;gt;wfc demo.xoml demo.cs&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Notice the use of the partial keyword in the class definition. In the end, the .xoml file is a partial definition of the workflow class, so the .cs file is another part of it and has to be marked as &amp;quot;partial&amp;quot;. Both compilations will yield the same assembly:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WFHelloWorldviatheCommandLine_140A3/image02.png"&gt;&lt;img border="0" height="302" src="http://www.bartdesmet.net/images/WFHelloWorldviatheCommandLine_140A3/image0_thumb.png" style="border:0px;" width="885" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Using the assembly in a host application is another concern of course. Basically you just have to compile the following piece of code with a reference to the demo.dll file generated above:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System.Threading;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System.Workflow.Runtime; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;namespace&amp;nbsp;&lt;/font&gt;&lt;/font&gt;FooBar&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;class &lt;/font&gt;&lt;/font&gt;Hello&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;public static void &lt;/font&gt;&lt;/font&gt;Main()&lt;br /&gt;&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; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;(&lt;font color="#008080"&gt;WorkflowRuntime&lt;/font&gt; workflowRuntime = &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/font&gt;&lt;font color="#008080"&gt;WorkflowRuntime&lt;/font&gt;())&lt;br /&gt;&amp;nbsp;&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; &lt;font color="#008080"&gt;AutoResetEvent&lt;/font&gt; waitHandle = &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/font&gt;&lt;font color="#008080"&gt;AutoResetEvent&lt;/font&gt;(false); &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowCompleted += &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;delegate&lt;/font&gt;&lt;/font&gt;(&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;object &lt;/font&gt;&lt;/font&gt;sender, &lt;font color="#008080"&gt;WorkflowCompletedEventArgs&lt;/font&gt; e)&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;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; waitHandle.Set();&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; }; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;WorkflowInstance&lt;/font&gt; instance = workflowRuntime.CreateWorkflow(&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/font&gt;(FooBar.&lt;font color="#008080"&gt;Demo&lt;/font&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; instance.Start(); &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; waitHandle.WaitOne();&lt;br /&gt;&amp;nbsp;&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/font&gt; &lt;/p&gt;&lt;p&gt;which might be a little difficult to add the reference to the System.Workflow assemblies which reside in the GAC. A more convenient demo approach is to merge the host application and the code-behind for the workflow into one single .cs file, like this:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System.Threading;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System.Workflow.Runtime; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;namespace&amp;nbsp;&lt;/font&gt;&lt;/font&gt;FooBar&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;class &lt;/font&gt;&lt;/font&gt;Hello&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;public static void &lt;/font&gt;&lt;/font&gt;Main()&lt;br /&gt;&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; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;(&lt;font color="#008080"&gt;WorkflowRuntime&lt;/font&gt; workflowRuntime = &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/font&gt;&lt;font color="#008080"&gt;WorkflowRuntime&lt;/font&gt;())&lt;br /&gt;&amp;nbsp;&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; &lt;font color="#008080"&gt;AutoResetEvent&lt;/font&gt; waitHandle = &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/font&gt;&lt;font color="#008080"&gt;AutoResetEvent&lt;/font&gt;(false); &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowCompleted += &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;delegate&lt;/font&gt;&lt;/font&gt;(&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;object &lt;/font&gt;&lt;/font&gt;sender, &lt;font color="#008080"&gt;WorkflowCompletedEventArgs&lt;/font&gt; e)&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;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; waitHandle.Set();&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; }; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;WorkflowInstance&lt;/font&gt; instance = workflowRuntime.CreateWorkflow(&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/font&gt;(FooBar.&lt;font color="#008080"&gt;Demo&lt;/font&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; instance.Start(); &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; waitHandle.WaitOne();&lt;br /&gt;&amp;nbsp;&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&lt;/font&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;partial class &lt;/font&gt;Demo&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;void&lt;/font&gt; sayHello_ExecuteCode(&lt;font color="#0000ff"&gt;object&lt;/font&gt; sender, &lt;font color="#008080"&gt;EventArgs&lt;/font&gt; e) &lt;br /&gt;&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; &lt;font color="#008080"&gt;Console&lt;/font&gt;.WriteLine(&lt;font color="#800000"&gt;&amp;quot;Hello World&amp;quot;&lt;/font&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;font face="courier new"&gt;&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;p&gt;Now compile this file (demo.cs) together with the .xoml file, as follows:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;gt;wfc /target:exe /r:System.Xml.dll demo.xoml demo.cs&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h1&gt;&lt;font color="#000080"&gt;MsBuild style&lt;/font&gt;&lt;/h1&gt;&lt;p&gt;There&amp;#39;s of course another approach that leans more towards Visual Studio 2005 compilation, i.e. using MsBuild. Assuming you have a file called demo.xoml:&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;lt;&lt;font color="#800000"&gt;SequentialWorkflowActivity&lt;/font&gt; &lt;font color="#ff0000"&gt;x:Name&lt;/font&gt;=&amp;quot;Demo&amp;quot; &lt;font color="#ff0000"&gt;x:Class&lt;/font&gt;=&amp;quot;FooBar.Demo&amp;quot;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &lt;font color="#ff0000"&gt;xmlns:x&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/winfx/2006/xaml/workflow&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/winfx/2006/xaml/workflow&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;CodeActivity&lt;/font&gt; &lt;font color="#ff0000"&gt;x:Name&lt;/font&gt;=&amp;quot;sayHello&amp;quot; &lt;font color="#ff0000"&gt;ExecuteCode&lt;/font&gt;=&amp;quot;sayHello_ExecuteCode&amp;quot;&lt;font face="courier new"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;x:Code&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;![CDATA[&lt;br /&gt;&lt;font color="#808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void sayHello_ExecuteCode(object sender, EventArgs e) &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; {&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; Console.WriteLine(&amp;quot;Hello World&amp;quot;);&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; }&lt;/font&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]]&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;x:Code&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;CodeActivity&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;lt;/&lt;font color="#800000"&gt;SequentialWorkflowActivity&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;and a file called hello.cs:&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System.Threading;&lt;br /&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;System.Workflow.Runtime; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;namespace&amp;nbsp;&lt;/font&gt;&lt;/font&gt;FooBar&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;class &lt;/font&gt;&lt;/font&gt;Hello&lt;br /&gt;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;public static void &lt;/font&gt;&lt;/font&gt;Main()&lt;br /&gt;&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; &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;using &lt;/font&gt;&lt;/font&gt;(&lt;font color="#008080"&gt;WorkflowRuntime&lt;/font&gt; workflowRuntime = &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/font&gt;&lt;font color="#008080"&gt;WorkflowRuntime&lt;/font&gt;())&lt;br /&gt;&amp;nbsp;&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; &lt;font color="#008080"&gt;AutoResetEvent&lt;/font&gt; waitHandle = &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;new &lt;/font&gt;&lt;/font&gt;&lt;font color="#008080"&gt;AutoResetEvent&lt;/font&gt;(false); &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowCompleted += &lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;delegate&lt;/font&gt;&lt;/font&gt;(&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;object &lt;/font&gt;&lt;/font&gt;sender, &lt;font color="#008080"&gt;WorkflowCompletedEventArgs&lt;/font&gt; e)&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;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; waitHandle.Set();&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; }; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#008080"&gt;WorkflowInstance&lt;/font&gt; instance = workflowRuntime.CreateWorkflow(&lt;font face="courier new"&gt;&lt;font color="#0000ff"&gt;typeof&lt;/font&gt;&lt;/font&gt;(FooBar.&lt;font color="#008080"&gt;Demo&lt;/font&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; instance.Start(); &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; waitHandle.WaitOne();&lt;br /&gt;&amp;nbsp;&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;p&gt;you can create a .csproj build file that contains this:&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;lt;&lt;font color="#800000"&gt;Project&lt;/font&gt; &lt;font color="#ff0000"&gt;DefaultTargets&lt;/font&gt;=&amp;quot;Build&amp;quot; &lt;font color="#ff0000"&gt;xmlns&lt;/font&gt;=&amp;quot;&lt;/font&gt;&lt;a href="http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;"&gt;&lt;font color="#0000ff" face="courier new"&gt;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&lt;/font&gt;&lt;/a&gt;&lt;font color="#0000ff" face="courier new"&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;PropertyGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;RootNamespace&lt;/font&gt;&amp;gt;&lt;font color="#000000"&gt;FooBar&lt;/font&gt;&amp;lt;/&lt;font color="#800000"&gt;RootNamespace&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;AssemblyName&lt;/font&gt;&amp;gt;&lt;font color="#000000"&gt;Demo&lt;/font&gt;&amp;lt;/&lt;font color="#800000"&gt;AssemblyName&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;OutputPath&lt;/font&gt;&amp;gt;&lt;font color="#000000"&gt;.&lt;/font&gt;&amp;lt;/&lt;font color="#800000"&gt;OutputPath&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;PropertyGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;ItemGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Reference&lt;/font&gt; &lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;System&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Reference&lt;/font&gt; &lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;System.Xml&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Reference &lt;/font&gt;&lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;System.Workflow.Activities&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Reference&lt;/font&gt; &lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;System.Workflow.ComponentModel&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Reference&lt;/font&gt; &lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;System.Workflow.Runtime&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;ItemGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;ItemGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Compile&lt;/font&gt; &lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;Hello.cs&amp;quot;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;DependentUpon&lt;/font&gt;&amp;gt;&lt;font color="#000000"&gt;demo.xoml&lt;/font&gt;&amp;lt;/&lt;font color="#800000"&gt;DependentUpon&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;SubType&lt;/font&gt;&amp;gt;&lt;font color="#000000"&gt;Component&lt;/font&gt;&amp;lt;/&lt;font color="#800000"&gt;SubType&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;Compile&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;ItemGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;ItemGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Content&lt;/font&gt; &lt;font color="#ff0000"&gt;Include&lt;/font&gt;=&amp;quot;demo.xoml&amp;quot;/&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/&lt;font color="#800000"&gt;ItemGroup&lt;/font&gt;&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Import&lt;/font&gt; &lt;font color="#ff0000"&gt;Project&lt;/font&gt;=&amp;quot;$(MSBuildBinPath)\Microsoft.CSharp.Targets&amp;quot; /&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;&lt;font color="#800000"&gt;Import&lt;/font&gt; &lt;font color="#ff0000"&gt;Project&lt;/font&gt;=&amp;quot;$(MSBuildExtensionsPath)\Microsoft\Windows Workflow Foundation\v3.0\Workflow.Targets&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/&lt;font color="#800000"&gt;Project&lt;/font&gt;&amp;gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;which can be built using:&lt;/p&gt;&lt;p&gt;&amp;gt;msbuild&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.bartdesmet.net/images/WFHelloWorldviatheCommandLine_140A3/image05.png"&gt;&lt;img border="0" height="448" src="http://www.bartdesmet.net/images/WFHelloWorldviatheCommandLine_140A3/image0_thumb1.png" style="border:0px;" width="677" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Enjoy command-line compiling WF-apps (for demo purposes only I hope)!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://community.bartdesmet.net/blogs/bart/archive/2006/12/07/WF-_2D00_-Hello-World-via-the-Command-Line.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" border="0" height="30" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://community.bartdesmet.net/blogs/bart/archive/2006/12/07/WF-_2D00_-Hello-World-via-the-Command-Line.aspx" width="164" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=12029" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>WF - Working with events and the ListenActivity</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/10/19/4588.aspx</link><pubDate>Thu, 19 Oct 2006 09:09:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4588</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4588</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/10/19/4588.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;This post builds upon the foundation created in &lt;A HREF="/blogs/bart/archive/2006/10/18/4587.aspx"&gt;yesterday's post&lt;/A&gt; about the &lt;STRONG&gt;HandleExternalEventActivity&lt;/STRONG&gt;. Please follow the instructions in that post before continuing with this one. As you've learned from this previous post, waiting for an external event to occur is a very powerful mechanism to drive execution of a workflow. There are a lot of scenarios however where you'll want to wait for more than one event at the same time, or you want to timeout such a wait for an event to get raised. To make this kind of dreams reality, WF has the &lt;STRONG&gt;ListenActivity&lt;/STRONG&gt; in its magic toolbox.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;The demo&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Take the solution you built in the &lt;A HREF="/blogs/bart/archive/2006/10/18/4587.aspx"&gt;previous post on working with events&lt;/A&gt;&amp;nbsp;and go to Workflow1.cs's designer view. It should look like this: &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;IMG src="http://www.bartdesmet.net/images/eventsdemo02.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Your next job is to transform this into the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;IMG src="http://www.bartdesmet.net/images/eventsdemobis01.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;An easy way to accomplish this is outlined below:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;Add a &lt;STRONG&gt;ListenActivity&lt;/STRONG&gt; below the WhileActivity.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;Rename the left branch of the ListenActivity to &lt;EM&gt;clientArrived&lt;/EM&gt; and the right branch to &lt;EM&gt;timeoutOccurred&lt;/EM&gt;.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;Drag and drop the &lt;EM&gt;clientArrival&lt;/EM&gt; and &lt;EM&gt;doWork&lt;/EM&gt; activities from the while loop to the &lt;STRONG&gt;left branch&lt;/STRONG&gt;.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;Delete the SequenceActivity from the WhileActivity's body.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;Drag and drop the ListenActivity to the body of our WhileActivity.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;Add a DelayActivity (set to 10 seconds) called &lt;EM&gt;timeout&lt;/EM&gt; to the &lt;STRONG&gt;right branch&lt;/STRONG&gt;, as well as a CodeActivity called &lt;EM&gt;oops&lt;/EM&gt; with the following ExecuteCode handler code:&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Cyan;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Oops! Timeout occurred"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ResetColor();&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;Basically, the ListenActivity blocks till one branch completes. Notice you can add additional branches, e.g. to listen to three, four, ... events at the same time:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/eventsdemobis02.jpg"&gt;&lt;/P&gt;
&lt;P&gt;When you try to execute this workflow, you'll see timeouts occurring when the client waits to long to enter&amp;nbsp;her name:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/eventsdemobis03.jpg"&gt;&lt;/P&gt;
&lt;P&gt;I'm sorry for the defaced console output, but hey that's not the goal of the demo is it?&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Waiting for one event to occur is a common requirement; waiting for multiple events can be even a more common requirement. WF makes it really easy to do this, without having to mess around with threading and waithandles (even more: in a stateful long-running world relying on additional runtime services like &lt;A HREF="/blogs/bart/archive/2006/10/14/4580.aspx"&gt;persistence&lt;/A&gt;) using the ListenActivity. I bet you'll find yourself leveraging the power of this activity on a regular basis, especially in combination with a DelayActivity to model timeouts. Now you know everything about waiting for events in WF, it's time to wake up yourself and don't wait any longer to explore WF! Cheers!&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4588" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>WF - Handling external events with HandleExternalEvent, External Data Exchange and Local Communications Services</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/10/18/4587.aspx</link><pubDate>Wed, 18 Oct 2006 08:04:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4587</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4587</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/10/18/4587.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In &lt;/FONT&gt;&lt;A HREF="/blogs/bart/archive/2006/10/17/4584.aspx"&gt;&lt;FONT face=Arial size=2&gt;yesterday's post&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Arial size=2&gt;, you learned that the vast majority of workflows need to exchange data with other parties to get their jobs done. Just one of the benefits of workflows is the possibility to visualize this kind of interaction by means of different activities, like the &lt;STRONG&gt;CallExternalMethodActivity&lt;/STRONG&gt; that was explained in the previous post. Based on a contract definition (read: interface) a workflow can be defined while the choice of the service implementation is left as a decision for the workflow host application. In today's post, we continue our journey on the Local Communication Services and External Data Exchange path with the &lt;STRONG&gt;HandleExternalEventActivity&lt;/STRONG&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Scenario&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;The &lt;STRONG&gt;CallExternalMethodActivity&lt;/STRONG&gt; explained in the &lt;A HREF="/blogs/bart/archive/2006/10/17/4584.aspx"&gt;previous post&lt;/A&gt; is used to perform methods calls from inside the workflow to some service. Based on an interface and method contract, the workflow can be defined. At runtime, an appropriate service implementation is attached to the workflow and chosen by the engine to process service requests. An example is a workflow calling to an order processing system in some way defined by the contract (e.g. PlaceOrder).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Beside making calls from the workflow to some party outside, one can also rely on the host application to notify the workflow when it needs to do something. This is done using the &lt;STRONG&gt;HandleExternalEventActivity&lt;/STRONG&gt; which makes a workflow block till the corresponding event (again in a contract-based manner) is raised by some service. As an example, think of a workflow waiting for approval based on some event (e.g. OrderApproved).&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;A simple demo&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#ff0000 size=2&gt;&lt;STRONG&gt;Workflow definition&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;As usual on this blog, we'll try to keep things simple and approachable, to focus on the basics of the topic discussed. Create a simple Sequential Workflow Console application called EventsDemo:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/eventsdemo01.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Next, create the following workflow definition in Workflow1.cs:&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/eventsdemo02.jpg"&gt;&lt;/P&gt;
&lt;P&gt;This needs some elaboration. On top, we have some CodeActivity called start with the simple ExecuteCode event handler displayed below. At the bottom, there's a similar activity with the event handler shown below as well:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; start_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Green;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Waiting for clients..."&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.ResetColor();&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; stop_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Red;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Served 5 clients; time for early retirement!"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.ResetColor();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Next, there's an activity called &lt;EM&gt;clientListener&lt;/EM&gt; of the type &lt;STRONG&gt;WhileActivity&lt;/STRONG&gt;. This one just loops till five clients have been served, based on the following Declarative Rule Condition:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;this.clientCount &amp;lt; 5&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;relying on the following private variable in the code-behind:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; clientCount = 0;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;A WhileActivity can only contain one single child activity. Because of this, a SequenceActivity is added to the body of the WhileActivity. Inside this SequenceActivity, two child activities are added:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;clientArrival&lt;/EM&gt; is of type HandleExternalEventActivity and will be discussed below shortly&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;doWork&lt;/EM&gt; is of type CodeActivity and has the following ExecuteCode event handler:&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; doWork_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Yellow;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Event captured - Hello {0}. You're client number {1}."&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;, args.Name, clientCount);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;.ResetColor();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT size=2&gt;The core of the workflow is the &lt;STRONG&gt;HandleExternalEventActivity&lt;/STRONG&gt; called &lt;EM&gt;clientArrival&lt;/EM&gt;. This activity works in a similar way as the CallExternalMethodActivity and relies on an interface and in this case an event to wait for. The logical next step is to define this interface (IBar.cs):&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; System;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;using&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; System.Workflow.Activities;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;namespace&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; EventsDemo&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ExternalDataExchange&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;]&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;interface&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;IBar&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; event&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt; Foo;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; [&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Serializable&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;]&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt; : &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;ExternalDataEventArgs&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; FooEventArgs(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Guid&lt;/FONT&gt;&lt;FONT size=2&gt; instanceId, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; name) : &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;base&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;(instanceId)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.name = name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; name;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Name&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; name; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { name = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;Notice the interface definition being annotated with the &lt;STRONG&gt;ExternalDataExchangeAttribute&lt;/STRONG&gt;, which is required for workflow to communicate with it using Local Communication Services. Next, the defined event has an event arguments object derived from &lt;STRONG&gt;ExternalDataEventArgs&lt;/STRONG&gt;. The constructor of this event arguments object is worth to mention because it requires a base call to one of the base class's constructors that require a workflow instance identifier to be passed on:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; FooEventArgs(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Guid&lt;/FONT&gt;&lt;FONT size=2&gt; instanceId, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; name) : &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;base&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;(instanceId)&lt;BR&gt;{&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;This is required for the workflow runtime to be able to correlate the event with the right workflow instance.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;When you've defined the interface with the event, you can continue to set up the HandleExternalEvent activity. Start by setting the InterfaceType to the IBar interface. Next, set the EventName to Foo. In order to capture the event arguments in the workflow instance to d something useful with it in a later stage, you can bind the &lt;EM&gt;e&lt;/EM&gt; parameter (à la EventArgs e) to some local variable:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; args;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Args&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; args; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { args = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;Finally hook up an event handler for the Invoked event of the HandleExternalEvent activity. This will be used to increment the counter that keeps track of the number of served clients (you could do this inside the &lt;EM&gt;doWork&lt;/EM&gt; CodeActivity too):&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; clientArrival_Invoked(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ExternalDataEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; clientCount++;&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;Notice you could use this event handler too in order to extract information from the event args that were raised with the exception.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Finally, the property grid of the HandleExternalEventActivity &lt;EM&gt;clientArrival&lt;/EM&gt; should look like this:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;img src="http://www.bartdesmet.net/images/eventsdemo03.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;STRONG&gt;The host&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;On to the host side now&lt;/FONT&gt;&lt;FONT size=2&gt;. What we want to do, is ask the end-user for a name and then raise the event to the workflow&amp;nbsp;instance to indicate a "client arrival". The workflow should then proceed in the WhileActivity loop and perform work for the newly arrived user.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;To do this, we'll first &lt;STRONG&gt;implement IBar&lt;/STRONG&gt; as follows:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Bar&lt;/FONT&gt;&lt;FONT size=2&gt; : &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;IBar&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;event&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt; Foo;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; RaiseEvent(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Guid&lt;/FONT&gt;&lt;FONT size=2&gt; instanceId, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; name)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; (Foo != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt; evt = Foo;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FooEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt; args = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;FooEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;(instanceId, name);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; evt(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;, args);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;Next, to establish the communication between the workflow and the "Bar" service, we need to register an ExternalDataExchangeService (from System.Workflow.Activities):&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;bar = &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Bar&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ExternalDataExchangeService&lt;/FONT&gt;&lt;FONT size=2&gt; svc = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ExternalDataExchangeService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;();&lt;BR&gt;workflowRuntime.AddService(svc);&lt;BR&gt;svc.AddService(bar);&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;I've created &lt;EM&gt;bar&lt;/EM&gt; as a local variable in the host class:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Bar&lt;/FONT&gt;&lt;FONT size=2&gt; bar;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;Once the workflow instance is started, we'll start a new thread (rather quick-n-dirty) to accept user input till the workflow terminates:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=2&gt;WorkflowInstance&lt;/FONT&gt;&lt;FONT size=2&gt; instance = workflowRuntime.CreateWorkflow(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;typeof&lt;/FONT&gt;&lt;FONT size=2&gt;(EventsDemo.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Workflow1&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;));&lt;BR&gt;instance.Start();&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Thread&lt;/FONT&gt;&lt;FONT size=2&gt; userInput = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Thread&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;(UserInput);&lt;BR&gt;userInput.Start(instance.InstanceId);&lt;BR&gt;&lt;BR&gt;waitHandle.WaitOne();&lt;BR&gt;&lt;BR&gt;userInput.Abort();&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;That is, the background thread &lt;EM&gt;userInput&lt;/EM&gt; is started with a parameter to indicate the workflow instance to raise events in. When the workflow completes (when &lt;EM&gt;waitHandle&lt;/EM&gt; is set), the background thread is aborted (there exist cleaner ways to implement this idea, but for demo purposes this should be okay). &lt;/FONT&gt;&lt;FONT size=2&gt;This background thread is defined as follows:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;static&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; UserInput(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; instanceId)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; for&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (; ; )&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread&lt;/FONT&gt;&lt;FONT size=2&gt;.Sleep(500); &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008000 size=2&gt;//dirty demo trick&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.Write(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"User name: "&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/FONT&gt;&lt;FONT size=2&gt; name = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.ReadLine();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;bar.RaiseEvent((&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&lt;STRONG&gt;&lt;U&gt;Guid&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;) instanceId, name);&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;The core line of code is indicated in bold and does the real work of notifying the workflow instance of the simulated "client arrival". Don't worry about the Thread.Sleep call which is just there to keep the console output nice and smooth in a very dirty way to keep things simple and clean.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;Now run the application, it should produce the following output (enter a few names and see what happens):&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;img src="http://www.bartdesmet.net/images/eventsdemo04.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Local communication between a workflow and external data services is an absolute must for a lot of workflow scenarios. In this post and the &lt;A HREF="/blogs/bart/archive/2006/10/17/4584.aspx"&gt;previous post&lt;/A&gt;, you learned how to establish this kind of communication with a workflow in both directions, by making method calls and by waiting for events to occur. Enjoy!&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4587" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>WF - Introducing External Data Exchange, the CallExternalMethodActivity and Local Communications Services</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/10/17/4584.aspx</link><pubDate>Tue, 17 Oct 2006 19:25:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4584</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4584</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/10/17/4584.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Workflows don't stand on their own; they need a host application to run in but in a lot of cases there's more: external services are needed to provide functionality to the workflow. You might think, let's just use&amp;nbsp;a CodeActivity to call into some piece of functionality but that doesn't offer enough flexibility in most cases. Okay, you can work with an interface and parameterize the workflow, but still the workflow doesn't reveal its intentions visibly: a CodeActivity is an opaque container where the visualized world of workflows is traded for procedural code again.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Enter the &lt;STRONG&gt;Communication Services&lt;/STRONG&gt;, part one. In this post, you'll learn how to exchange data with the workflow by hooking in a "external data exchange service".&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;CallExternalMethodActivity&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;At the core of external data exchange is the CallExternalMethodActivity. In a later post, we'll focus on HandleExternalEvent but for now, let's just rely on plain simple method calls. The scenario is the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;We need a workflow to get the job done (for reasons that may vary a lot, which have been discussed extensively already).&lt;/LI&gt;
&lt;LI&gt;It can't be 100% self-contained and has to rely on external services to process things, for example to make an order.&lt;/LI&gt;
&lt;LI&gt;This external service communication needs a big deal of genericity, so that it can be replaced by an alternative implementation when required. In other words, it needs to be &lt;STRONG&gt;contract-based&lt;/STRONG&gt;.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;EM&gt;(And no, it isn't a web service we want to call, because in that case we could rely on InvokeWebService.)&lt;/EM&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Demo&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;A workflow definition&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Right, on to the demo with a somewhat simplified contract: let's call a simple calculator to get things done (I don't want to get the curse of the bad demo gods :-)). Start by creating a simple console-based workflow application:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;img src="http://www.bartdesmet.net/images/externaldatademo01.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Next, add a single CallExternalMethodActivity from the toolbox to the workflow definition as shown below:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;img src="http://www.bartdesmet.net/images/externaldatademo02.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;This is what you should get to see when you set the properties correctly as outlined below. First, go to the code behind of the workflow and add three properties:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; a;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; A&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; a; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { a = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; B&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { b = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; result;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Result&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; result; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { result = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Now, add an interface to the project called ICalculator:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT face="Courier New"&gt;[&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;&lt;STRONG&gt;&lt;U&gt;ExternalDataExchange&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;]&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;interface&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;ICalculator&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; int&lt;/FONT&gt;&lt;FONT size=2&gt; Add(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; int&lt;/FONT&gt;&lt;FONT size=2&gt; Subtract(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; int&lt;/FONT&gt;&lt;FONT size=2&gt; Multiply(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; int&lt;/FONT&gt;&lt;FONT size=2&gt; Divide(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; b);&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Notice the use of the &lt;A href="http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.activities.externaldataexchangeattribute.aspx"&gt;ExternalDataExchangeAttribute&lt;/A&gt;, which lives in System.Workflow.Activities. This indicates the interface acts as the contract for external data exchange.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Now go back to the designer and set the CallExternalMethodActivity properties. Start by specifying the InterfaceType:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;img src="http://www.bartdesmet.net/images/externaldatademo03.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Next, set the MethodName to Add. Then&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;, set the parameters a, b and (ReturnValue) that appear in the property grid to point to the properties A, B and Result respectively:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;img src="http://www.bartdesmet.net/images/externaldatademo04.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;If you've done things correctly, this should result in the following:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;img src="http://www.bartdesmet.net/images/externaldatademo05.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Right, so now your workflow knows how to transform some input parameters into the corresponding output.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#ff0000 size=2&gt;&lt;STRONG&gt;Letting the host know about data services&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;That's all what's needed for the workflow definition itself. On to the &lt;STRONG&gt;host&lt;/STRONG&gt; now (Program.cs). First, we'll parameterize the workflow instantiation as follows:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;Dictionary&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; parameters = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Dictionary&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT size=2&gt;&amp;gt;();&lt;BR&gt;parameters.Add(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"A"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT size=2&gt;, 1);&lt;BR&gt;parameters.Add(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"B"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;, 2);&lt;/U&gt;&lt;/STRONG&gt;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowInstance&lt;/FONT&gt;&lt;FONT size=2&gt; instance = workflowRuntime.CreateWorkflow(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;typeof&lt;/FONT&gt;&lt;FONT size=2&gt;(ExternalDataDemo.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Workflow1&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;), &lt;STRONG&gt;&lt;U&gt;parameters&lt;/U&gt;&lt;/STRONG&gt;);&lt;BR&gt;instance.Start();&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Next, create some class that implements ICalculator. In this case this is very straightforward since we live in the same project as the workflow definition. In reality you'd have to reference the assembly with the interface definition of course. For the sake of the demo, a simple implementation as a nested class inside Program will meet our needs:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;class&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;CalculatorService&lt;/FONT&gt;&lt;FONT size=2&gt; : &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;ICalculator&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; #region&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; ICalculator Members&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; Add(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; a + b;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; Subtract(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; a - b;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; Multiply(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; a * b;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; Divide(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; a, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; b)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; a / b;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; #endregion&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Now it's time to hook in this service to the workflow runtime, so that instances can rely on it to get their jobs done. This is done in the Program class again, as follows:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;ExternalDataExchangeService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; edx = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ExternalDataExchangeService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;();&lt;BR&gt;workflowRuntime.AddService(edx); &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008000 size=2&gt;//keep this order!&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;edx.AddService(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;CalculatorService&lt;/FONT&gt;&lt;FONT size=2&gt;()); &lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;//keep this order!&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;It's important to keep the order of the last two lines, otherwise you'll end up with an exception. Also, import the System.Workflow.Activities namespace that contains the &lt;A href="http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.activities.externaldataexchangeservice.aspx"&gt;ExternalDataExchangeService&lt;/A&gt; class. This class acts as a container for all external data exchange services, i.e. implementations of interfaces that were annotated with the ExternalDataExchangeAttribute earlier on. &lt;EM&gt;You can only have one implementation of each service.&lt;/EM&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Finally, to get the result back, we'll change the WorkflowCompleted event handler as displayed below:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; res = 0;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;AutoResetEvent&lt;/FONT&gt;&lt;FONT size=2&gt; waitHandle = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;AutoResetEvent&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;workflowRuntime.WorkflowCompleted += &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;delegate&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowCompletedEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;res = (&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt;) e.OutputParameters[&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Result"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;];&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&amp;nbsp; waitHandle.Set();&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;...&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In here, &lt;EM&gt;res&lt;/EM&gt; is a variable declared on top of the the Main method which gets printed out at the end of the method:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;WorkflowInstance&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; instance = workflowRuntime.CreateWorkflow(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;typeof&lt;/FONT&gt;&lt;FONT size=2&gt;(ExternalDataDemo.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Workflow1&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;), parameters);&lt;BR&gt;instance.Start();&lt;BR&gt;&lt;BR&gt;waitHandle.WaitOne();&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#008080 size=2&gt;Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(res);&lt;/P&gt;&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;The result when executing should be obvious :-).&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Exchanging data with external parties should be apparent when looking at the workflow definition. Therefore, one has created the CallExternalMethodActivity to encapsulate such a call for external data. By doing so, external data exchange has the potential to become just yet another service, like &lt;A HREF="/blogs/bart/archive/2006/10/15/4582.aspx"&gt;tracking&lt;/A&gt; and &lt;A HREF="/blogs/bart/archive/2006/10/14/4580.aspx"&gt;persistence&lt;/A&gt;. In the next post, we'll talk about events. Enjoy!&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4584" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>WF - Using the WorkflowMonitor in combination with Dynamic Updates</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/10/16/4585.aspx</link><pubDate>Mon, 16 Oct 2006 20:15:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4585</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4585</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/10/16/4585.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In the past, I've been talking about making a workflow dynamic by applying changes to it at runtime:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;&lt;A HREF="/blogs/bart/archive/2006/08/28/4322.aspx"&gt;WF&amp;nbsp;- How to make a workflow dynamic? - Part 1&lt;/A&gt;&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial size=2&gt;&lt;A HREF="/blogs/bart/archive/2006/08/31/4369.aspx"&gt;WF - How to make a workflow dynamic? - Part 2&lt;/A&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;A HREF="/blogs/bart/archive/2006/10/15/4582.aspx"&gt;Yesterday&lt;/A&gt;, you learned how to use tracking (and persistence) services to visualize what's going on inside a workflow in flight, using the WorkflowMonitor sample application that comes with the Windows SDK. Today, we'll combine both the dynamic adaptation of a workflow with tracking services.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Modifying the WorkflowMonitor&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;As discussed &lt;A HREF="/blogs/bart/archive/2006/10/15/4582.aspx"&gt;yesterday&lt;/A&gt;, the &lt;STRONG&gt;WorkflowMonitor&lt;/STRONG&gt; tracks workflows by polling a tracking database used by WF. To visualize what's a workflow keeping itself busy with, it relies on the workflow definition type that gets loaded in the &lt;STRONG&gt;workflow designer&lt;/STRONG&gt; that's rehosted by the sample application. However, when making dynamic changes, the WorkflowMonitor doesn't visualize the modifications made&amp;nbsp;to the workflow, because the type doesn't get &lt;STRONG&gt;reload&lt;/STRONG&gt;ed. To make things work in a quick-n-dirty fashion, you'll need to change the WorkflowMonitor sample a bit (one line to be precise).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Go to MainForm.cs and locate the method called &lt;STRONG&gt;UpdateActivities&lt;/STRONG&gt;. Change the code as follows (only a few lines are displayed, just enough for you to find the spot where modification is needed):&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;...&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#008080 size=2&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;ListViewItem&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; currentWorkflow = listViewWorkflows.SelectedItems[0];&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; (currentWorkflow != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Guid&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; workflowInstanceId = workflowStatusList[(currentWorkflow.SubItems[0]).Text].InstanceId;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; SqlTrackingWorkflowInstance&lt;/FONT&gt;&lt;FONT size=2&gt; sqlTrackingWorkflowInstance = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;FONT size=2&gt; == monitorDatabaseServiceValue.TryGetWorkflow(workflowInstanceId, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; sqlTrackingWorkflowInstance))&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;//Edited by Bart De Smet - 10/05/06&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;GetWorkflowDefinition(workflowInstanceId);&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;//End edit&lt;/U&gt;&lt;/STRONG&gt;&lt;BR&gt;&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;&amp;nbsp; listViewActivities.Items.Clear();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; activityStatusListValue.Clear();&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Dynamic updates&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;To keep things easy, I'll rely on the results of &lt;A HREF="/blogs/bart/archive/2006/10/15/4582.aspx"&gt;yesterday's work&lt;/A&gt;, so follow those instructions first and make sure the app runs fine. Then go to Workflow1.cs in the TrackingDemoLibrary project and change the ExecuteCode eventhandler for allowAccess like this:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; allowAccess_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Green;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"You're granted access"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.ResetColor();&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;WorkflowChanges&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT size=2&gt; wc = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowChanges&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;this&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;);&lt;BR&gt;&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;CodeActivity&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT size=2&gt; hello = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;CodeActivity&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"hello"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;);&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;hello.ExecuteCode += &lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;&lt;U&gt;(hello_ExecuteCode);&lt;BR&gt;&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;IfElseActivity&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#000000 size=2&gt; ageChecker = (&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IfElseActivity&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;)wc.TransientWorkflow.Activities[&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"ageChecker"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New" color=#000000&gt;&lt;STRONG&gt;&lt;U&gt;];&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;IfElseBranchActivity&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT size=2&gt; plusEighteen = (&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IfElseBranchActivity&lt;/FONT&gt;&lt;FONT size=2&gt;)ageChecker.GetActivityByName(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"plusEighteen"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;);&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;plusEighteen.Activities.Add(hello);&lt;BR&gt;&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; &lt;STRONG&gt;&lt;U&gt;this&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;U&gt;.ApplyWorkflowChanges(wc);&lt;/U&gt;&lt;/STRONG&gt;&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Next, add another delay on top of the workflow, set to 10 seconds. This will give us the opportunity to see the dynamic change happen in the WorkflowMonitor:&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/dynmonitor03.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Recompile and &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;make sure to re-register the workflow definition assembly in the GAC&lt;/FONT&gt;&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/dynmonitor02.jpg"&gt;&lt;/P&gt;
&lt;P&gt;You might need to recreate the tracking database too (that the easy way to clean it when doing demos), as explained in the &lt;A HREF="/blogs/bart/archive/2006/10/15/4582.aspx"&gt;post on Tracking Services&lt;/A&gt;. Just drop the SqlTrackingDatabase, create it again and execute the two .sql scripts.&lt;/P&gt;
&lt;P&gt;Now start the &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;adapted (see above) WorkflowMonitor&lt;/FONT&gt;&lt;/STRONG&gt; and then start the TrackingDemo solution. Keep an eye on the WorkflowMonitor and see what happens:&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/dynmonitor04.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/dynmonitor05.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/dynmonitor06.jpg"&gt;&lt;/P&gt;
&lt;P&gt;The result of the execution looks as follows thanks to dynamic adaptation:&lt;/P&gt;
&lt;P&gt;&lt;img src="http://www.bartdesmet.net/images/dynmonitor01.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Tracking in a world of dynamic updates is even more interesting and with one simple change to the WorkflowMonitor sample code, one creates a very appealing piece of tracking functionality. Have fun!&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4585" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>WF - Working with Tracking Services</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/10/15/4582.aspx</link><pubDate>Sun, 15 Oct 2006 10:15:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4582</guid><dc:creator>bart</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4582</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/10/15/4582.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In the &lt;/FONT&gt;&lt;A HREF="/blogs/bart/archive/2006/10/14/4580.aspx"&gt;&lt;FONT face=Arial size=2&gt;previous post&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Arial size=2&gt; I've covered the use of persistence services with Windows Workflow Foundation to enable long-running workflows in a reliable way. However, there's still another dark side to long-running workflows that needs a solution: what's happening inside? As you can imagine, a workflow in progress can be blocked waiting for a lot of things, such as the expiration of a timer to indicate a timeout (e.g. by putting a DelayActivity in parallel with another activity using a ParallelActivity) or a wait for an external chunk of data to arrive. In order to visualize what's going on inside, at runtime, the WF Gods created tracking services.&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Getting started&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Just like persistence services, tracking services&amp;nbsp;rely on some store to put information - in casu tracking information - in. Again, WF comes with a SQL Server enabled service out of the box, called the &lt;A href="http://windowssdk.msdn.microsoft.com/en-us/library/ms665167.aspx"&gt;SqlTrackingService&lt;/A&gt;. There's quite a bit to tell about tracking services, but we'll stick with the basics in this post. Nevertheless, a short list of cool things:&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Filtering tracking information using &lt;STRONG&gt;tracking profiles&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Querying tracked information using &lt;STRONG&gt;SqlTrackingQuery&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;These might get covered in much more detail somewhere in the future. As usual, in case you have questions, you can contact me too.&lt;/P&gt;
&lt;P&gt;Right, on the the real stuff now. To enable tracking services using SQL Server (2000, 2005, MSDE, Express) we need to create a tracking database first. We'll use SQL Server 2005 Express Edition in this post (&lt;A href="http://msdn.microsoft.com/vstudio/express/sql/download/"&gt;download here&lt;/A&gt;) with SQL Server Management Studio Express installed on the machine:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Connect to the database server:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo01.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Create a new database called SqlTrackingDemo:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo02.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Now define the database structure and logic required by tracking services, based on two .sql scripts that ship with WF in the %windir%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN folder:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo03.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Execute (in order) &lt;STRONG&gt;Tracking_Schema.sql&lt;/STRONG&gt; and &lt;STRONG&gt;Tracking_Logic.sql&lt;/STRONG&gt;, while making sure you've selected the newly created database from step 2:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo04.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Finally you should find a bunch of tables and stored procedures in the database (check this).&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;A tracking-enabled workflow project&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#ff0000 size=2&gt;&lt;STRONG&gt;A simple solution&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Create a new&amp;nbsp;Sequential Workflow Console Application first, called &lt;STRONG&gt;TrackingDemo&lt;/STRONG&gt;:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo05.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Remove Workflow1 from the Solution Explorer and add a new Sequential Workflow Library project to the solution, called &lt;STRONG&gt;TrackingDemoLibrary&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo06.jpg"&gt;&lt;/P&gt;
&lt;P&gt;This step is required because we'll use our workflow definition to visualize tracking information and to do so, the assembly containing the workflow definition will be put in the GAC (as shown later on). Next, &lt;STRONG&gt;add a reference&lt;/STRONG&gt; to the TrackingDemoLibrary project in the TrackingDemo (host) project:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo07.jpg"&gt;&lt;/P&gt;
&lt;P&gt;In the code of the host application (Program.cs) change the call to CreateWorkflow as follows:&lt;/P&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;WorkflowInstance&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; instance = workflowRuntime.CreateWorkflow(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;typeof&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;U&gt;&lt;STRONG&gt;TrackingDemoLibrary.&lt;/STRONG&gt;&lt;/U&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&lt;U&gt;&lt;STRONG&gt;Workflow1&lt;/STRONG&gt;&lt;/U&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;));&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;Finally, go the &lt;STRONG&gt;project properties of TrackingDemoLibrary&lt;/STRONG&gt; and make the assembly strong-named:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo08.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Defining the workflow&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now go to Workflow1 in the TrackingDemoLibrary project. First, &lt;STRONG&gt;parameterize&lt;/STRONG&gt; the workflow by adding two&amp;nbsp;properties to the code:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; firstName;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; FirstName&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; firstName; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { firstName = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;; }&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; age;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Age&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; get&lt;/FONT&gt;&lt;FONT size=2&gt; { &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;return&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; age; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; set&lt;/FONT&gt;&lt;FONT size=2&gt; { age = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;value&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Now create the following &lt;STRONG&gt;workflow definition&lt;/STRONG&gt;:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo09.jpg"&gt;&lt;/P&gt;
&lt;P&gt;In here, the IfElseActivity's plusEighteen branch relies on a &lt;STRONG&gt;Declarative Rule Condition&lt;/STRONG&gt; defined as follows:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo10.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo11.jpg"&gt;&lt;/P&gt;
&lt;P&gt;The ExecuteCode event handlers for the different CodeActivity activities are defined like this:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; welcome_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Welcome "&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; + firstName);&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; allowAccess_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Green;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"You're granted access"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.ResetColor();&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; denyAccess_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Red;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"You're denied access"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.ResetColor();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Finally, the delay activities in the workflow were added to simulate long-running operations and have a timeout value set to 10 seconds.&lt;/P&gt;
&lt;P&gt;To test things, go to the Program.cs file and change the workflow instance creation code to pass through parameters:&lt;/P&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT face="Courier New"&gt;Dictionary&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt; parameters = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Dictionary&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;&amp;gt;();&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;STRONG&gt;&lt;U&gt;parameters.Add(&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#800000 size=2&gt;"FirstName"&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Bart"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;);&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;STRONG&gt;&lt;U&gt;parameters.Add(&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;&lt;STRONG&gt;&lt;U&gt;"Age"&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;, 23);&lt;BR&gt;&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowInstance&lt;/FONT&gt;&lt;FONT size=2&gt; instance = workflowRuntime.CreateWorkflow(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;typeof&lt;/FONT&gt;&lt;FONT size=2&gt;(TrackingDemoLibrary.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Workflow1&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;), &lt;STRONG&gt;&lt;U&gt;parameters&lt;/U&gt;&lt;/STRONG&gt;);&lt;BR&gt;instance.Start();&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;No magic yet:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo12.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Track it&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Time to enable tracking. This is done by adding just one single line of code to the host code (Program.cs):&lt;BR&gt;&lt;BR&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;using&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; System.Workflow.Runtime.Tracking;&lt;BR&gt;&lt;BR&gt;...&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;workflowRuntime.AddService(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;SqlTrackingService&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Data Source=localhost\\SQLEXPRESS;Initial Catalog=SqlTrackingDemo;Integrated Security=SSPI;"&lt;/FONT&gt;&lt;FONT size=2&gt;));&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;Now, execute the application once more and then go to the SQL Server Management Studio Express to execute the following query:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;use&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; SqlTrackingDemo&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;exec&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; dbo&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;GetWorkflows&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;This will result in something like this (a few columns were hidden in the screenshot):&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo13.jpg"&gt;&lt;/P&gt;
&lt;P&gt;In here you can see the identifier of the workflow instance as well as information about the workflow type. Other database tables include much more detailed information about the current state the workflow is in, effectively enabling tracking scenarios. Instead of doing low level work with these tables or stored procedures, we'll use a monitor application to see what's going on.&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Lights on the WorkflowMonitor&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;When you install the Windows SDK, a folder with samples is created on the system, typically in %programfiles%\Microsoft SDKs\Windows\v6.0\Samples:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo14.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Extract the WFSamples.zip folder to some location on your system. In the &lt;STRONG&gt;Applications\WorkflowMonitor\CS&lt;/STRONG&gt; subfolder of the samples, you'll find a WorkflowMonitor application that we'll take a look at now. Open it in Visual Studio 2005.&lt;/P&gt;
&lt;P&gt;Now run the application. After a few seconds, the app will crash with the following error message:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo15.jpg"&gt;&lt;/P&gt;
&lt;P&gt;This is because we didn't use the default configuration for tracking (i.e. different database name etc). However, we get the opportunity to change the settings right away:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo16.jpg"&gt;&lt;/P&gt;
&lt;P&gt;The settings shown above are the valid ones in our case, using SQL Server 2005 Express with the right database name and a polling time of 5 seconds.&lt;/P&gt;
&lt;P&gt;When you now try to start the monitoring (using the green "play" button) you'll likely see the following error (or something similar). You might need to restart the application to see the message popping up too:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo17.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Basically this means that the WorkflowMonitor is able to get the workflows using GetWorkflows but now tries to load the type specified in the database to visualize the workflows (which may be&amp;nbsp;in flight). For the WorkflowMonitor to find our &lt;STRONG&gt;TrackingDemoLibrary.Workflow1&lt;/STRONG&gt; type, it will need to find the assembly containing the definition. You can either copy the dll file to the bin\Debug (or bin\Release depending on how you're running the WorkflowMonitor sample) folder of the WorkflowMonitor or register the workflow definition in the GAC. We choose the latter one:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo18.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Now restart the WorkflowMonitor and you should see something like this:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo19.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Notice the mark signs indicate the followed path during execution. It's a very interesting time investment to look at the code of this sample to find out how the workflow information is queried using &lt;STRONG&gt;SqlTrackingQuery&lt;/STRONG&gt;. This sample is also interesting because of the &lt;STRONG&gt;designer rehosting&lt;/STRONG&gt; used to visualize the workflow in the right-hand side pane. I'll cover designer rehosting some time in the future on this blog too.&lt;/P&gt;
&lt;P&gt;Now, run our workflow application again while the monitor is polling the tracking database. Contrary to what you might expect, you won't see a new workflow instance appearing in the list right away. This happens because tracking only performs its job when asked so, e.g. because of a persistence opportunity (this statement is somewhat simplified, check out the docs to get full info on how the system works, related to work batches and so on). As an exercise, try to combine persistence (see &lt;A HREF="/blogs/bart/archive/2006/10/14/4580.aspx"&gt;previous post&lt;/A&gt;) with tracking to track a workflow in progress. You'll end up with a piece of hosting code like this:&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;workflowRuntime.AddService(&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;SqlWorkflowPersistenceService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;(&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Data Source=localhost\\SQLEXPRESS;Initial Catalog=SqlPersistenceDemo;Integrated Security=SSPI;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;,&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;,&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.FromHours(1.0),&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; TimeSpan&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.FromSeconds(5.0)&lt;BR&gt;&amp;nbsp;&amp;nbsp; )&lt;BR&gt;);&lt;BR&gt;&lt;BR&gt;workflowRuntime.AddService(&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;SqlTrackingService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;(&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#800000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Data Source=localhost\\SQLEXPRESS;Initial Catalog=SqlTrackingDemo;Integrated Security=SSPI;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; )&lt;BR&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Chances are high your app will block or throw an exception. This is because the system needs to connect to the two databases at the same time in a transactional manner. To have this work, you need to start the &lt;STRONG&gt;DTC service&lt;/STRONG&gt; on your machine:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo20.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Now execute the app again and you should see the following in the monitor:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/trackingdemo21.jpg"&gt;&lt;/P&gt;
&lt;P&gt;As you can see, it's now possible to &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;monitor a workflow in flight&lt;/FONT&gt;&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;Note:&lt;/U&gt;&lt;/STRONG&gt; An alternative approach to avoid the DTC problem is to use the - fasten your seatbelts - &lt;A href="http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sharedconnectionworkflowcommitworkbatchservice.aspx"&gt;SharedConnectionWorkflowCommitBatchService&lt;/A&gt; service instead of a combination of the tracking service and the persistence service. As the name implies, this one uses a shared connection for both, effectively avoiding distributed transactions and the need for DTC to be enabled and started on the machine. I won't cover this here.&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The use of long-running workflows in combination with a lot of services can turn the whole thing in a opaque box without you (and managers) knowing what's going on inside. Tracking services are the window into the internals of workflow instances in all their states, even when in progress. Combining this goodness with things like designer rehosting can open up a lot of great scenarios as shown in the WorkflowMonitor sample.&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4582" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>WF - Working with Persistence Services</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/10/14/4580.aspx</link><pubDate>Sun, 15 Oct 2006 03:48:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4580</guid><dc:creator>bart</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4580</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/10/14/4580.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In the past, I've been &lt;/FONT&gt;&lt;A HREF="/blogs/bart/archive/category/1004.aspx"&gt;&lt;FONT face=Arial size=2&gt;writing about WF&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Arial size=2&gt; quite a bit. If you haven't read these articles already, you might find it interesting to check these out first before digging into this one. That being said, this post will focus on &lt;STRONG&gt;persistence services&lt;/STRONG&gt; (also known as &lt;EM&gt;state persistence services&lt;/EM&gt;).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Why persistence?&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Before we dive deeper in the technical details, let's answer a crucial question: why persistence? As you probably know by now, workflows can be defined (at least partially) as a great tool to visualize either human workflow (e.g. approval processes) or machine workflow (e.g. business integration scenarios). Instead of writing procedural code, one creates a flow diagram or state diagram that represents the underlying logic that gets managed by the workflow runtime and engine. Read my &lt;A HREF="/blogs/bart/archive/2006/08/27/4278.aspx"&gt;WF introduction post&lt;/A&gt; for more information on this.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;A common question is why one would prefer to use workflow instead of classic procedural code. There are a lot of answers to the question, one of which relates to the &lt;STRONG&gt;graphical&lt;/STRONG&gt; aspect of a workflow that makes it more approachable and easier to understand. Another good answer is the support for scenarios that would end up with a rather high level &lt;STRONG&gt;complexity&lt;/STRONG&gt; in procedural code, like parallel execution, data exchange with other components, transactional support, etc. Yet another one - the one that will interest us most - is a set of &lt;STRONG&gt;runtime services&lt;/STRONG&gt; available to cope with more complex situations, including persistence services.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Beside the distinction of state workflows and sequential workflows and the distinction between machine workflows and human workflows, one can also draw a line between &lt;STRONG&gt;long-running&lt;/STRONG&gt; and non-long-running workflows. It's not atypical (even more, rather typical) for workflows to be long-running. For example, approval processes will require human interaction by one or more parties to continue the workflow execution. Yet another example is a business integration application that waits for external data to arrive. In such a case we say a workflow to be &lt;STRONG&gt;idled&lt;/STRONG&gt;. Needless to say, it would be a waste of resources (and even unreliable) to keep state of an idle workflow in memory. That's why we need persistence services.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;The basics: getting idle&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;We'll start by taking a look at a workflow becoming idle. Start by creating a simple sequential workflow:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo01.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;To force a workflow getting idle, we can use the DelayActivity. So, define the following workflow, containing a DelayActivity with the delay set to 10 seconds:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo02.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo03.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Next, define the ExecuteCode event handler for both CodeActivity activities as follows:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; codeActivity1_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Green;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"CodeActivity1 speaking"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.ResetColor();&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; codeActivity2_ExecuteCode(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.ForegroundColor = &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ConsoleColor&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Green;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"CodeActivity2 speaking"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.ResetColor();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;When you launch this workflow application, no surprises will happen. At least not visibly (yet). The workflow will be launched, the "CodeActivity1 speaking" message will be printed out, the workflow will pause for 10 seconds, and then "CodeActivity2 speaking" will appear. Behind the scenes however, the workflow is idled when the delay activity is started. To visualize this, go to the host application's Program.cs file and hook in an event handler for the WorkflowIdled event as show below:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;Program&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; Main(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;[] args)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowRuntime&lt;/FONT&gt;&lt;FONT size=2&gt; workflowRuntime = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowRuntime&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AutoResetEvent&lt;/FONT&gt;&lt;FONT size=2&gt; waitHandle = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;AutoResetEvent&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowCompleted += &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;delegate&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowCompletedEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e) {waitHandle.Set();};&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowTerminated += &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;delegate&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowTerminatedEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.WriteLine(e.Exception.Message);&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; waitHandle.Set();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;U&gt;workflowRuntime.WorkflowIdled += &lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;&amp;gt;(workflowRuntime_WorkflowIdled);&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WorkflowInstance&lt;/FONT&gt;&lt;FONT size=2&gt; instance = workflowRuntime.CreateWorkflow(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;typeof&lt;/FONT&gt;&lt;FONT size=2&gt;(PersistenceDemo.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Workflow1&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; instance.Start();&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; waitHandle.WaitOne();&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;STRONG&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; workflowRuntime_WorkflowIdled(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#008080 size=2&gt;Console&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Idled "&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt; + e.WorkflowInstance.InstanceId);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;STRONG&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;/STRONG&gt;&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Run the application now. It should print the following before it completes (i.e. screenshot taken during the delay activity execution):&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo04.jpg"&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;How persistence works&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;When a workflow gets idle, it can be persisted, so that it can be unloaded from memory. A persistence service inherits from the &lt;A href="http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.workflowpersistenceservice.aspx"&gt;System.Workflow.Hosting.WorkflowPersistenceService&lt;/A&gt; base class that's used by the workflow engine to perform persistence. I recommend you to check out this class. Workflow comes with a SQL Server driven persistence service out of the box, defined in &lt;A href="http://windowssdk.msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sqlworkflowpersistenceservice.aspx"&gt;System.Workflow.Hosting.SqlWorkflowPersistenceService&lt;/A&gt;.&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;When a workflow gets idle, the system checks in the registered services to find a persistence service, if any. If it finds when, the persistence service gets called to perform the persistence. Next, the system uses the persistence information to find out about the "next timer expiration" to wake up the idled workflow instance when required, so that it can continue its job executing.&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Setting up persistence&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;The first step to set up persistence using SQL Server (2000, MSDE, 2005, Express) is to create the persistence database. In this post, I'll use &lt;STRONG&gt;SQL Server 2005 Express Edition&lt;/STRONG&gt; to illustrate the persistence service. You can download the software &lt;A href="http://msdn.microsoft.com/vstudio/express/sql/download/"&gt;over here&lt;/A&gt;. Don't forget to install &lt;STRONG&gt;SQL Server Management Studio Express&lt;/STRONG&gt; too.&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Open SQL Server Management Studio Express and connect to the server (typically localhost\SQLEXPRESS):&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo05.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Next, create a new database called SqlPersistenceDemo, either by invoking CREATE DATABASE or by using the tools:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo06.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;Now it's time to define the database by executing the WF .sql scripts provided in %windir%\Microsoft.NET\Framework\v3.0\Windows Workflow Foundation\SQL\EN:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo07.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;First, execute &lt;STRONG&gt;SqlPersistenceService_Schema.sql&lt;/STRONG&gt;, then execute &lt;STRONG&gt;SqlPersistenceService_Logic.sql&lt;/STRONG&gt;. Make sure to use the right database when you execute the scripts (SqlPersistenceDemo):&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo08.jpg"&gt;&lt;BR&gt;&lt;/LI&gt;
&lt;LI&gt;You're ready. The persistence database should contain the following tables and sprocs:&lt;BR&gt;&lt;BR&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo09.jpg"&gt;&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Now, we can alter the code to support persistence. This is done in&amp;nbsp;the host application by creating an instance of the SqlWorkflowPersistence class and registering it as a service with the workflow runtime:&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;workflowRuntime.AddService(&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;SqlWorkflowPersistenceService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;(&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Initial Catalog=SqlPersistenceDemo;Data Source=localhost\\SQLEXPRESS;Integrated Security=SSPI;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;,&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;,&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.FromHours(1.0),&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TimeSpan&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.FromSeconds(5.0)&lt;BR&gt;&amp;nbsp;&amp;nbsp; )&lt;BR&gt;);&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;The first parameter is straightforward and points to the database. In this case I'm using the SQLEXPRESS instance and connecting using windows integrated authentication. The second parameter is called "unloadOnIdle" which unloads the workflow when it's idled. This is the point in time where persistence happens. The third parameter isn't relevant for our elaboration right now and is used when multiple hosts can hydrate/dehydrate workflow instances from the database (it sets the ownership duration for the host, so that if another host tries to load the instance during that interval, it doesn't succeed in doing so and an exception will be thrown). The last parameter specifies the loading interval used to check whether a workflow instance has to be dehydrated (i.e. loaded from the database). We set this value to 5 seconds for the sake of the demo.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Tip:&lt;/STRONG&gt; Check out SqlConnectionStringBuilder is you didn't do so yet and you want a more structured approach to create a connection string:&lt;/P&gt;&lt;FONT color=#008080 size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;SqlConnectionStringBuilder&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; sb = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;SqlConnectionStringBuilder&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;();&lt;BR&gt;sb.IntegratedSecurity = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;sb.DataSource = &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"localhost\\SQLEXPRESS"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;sb.InitialCatalog = &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"SqlPersistenceDemo"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; connString = sb.ToString();&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Testing it&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Time to test. But before we do so, let's hook in another set of event handlers to find out about unload/load/persist events for the workflow:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;workflowRuntime.WorkflowIdled += &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;gt;(workflowRuntime_WorkflowIdled);&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowLoaded += &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt;(workflowRuntime_WorkflowLoaded);&lt;BR&gt;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowUnloaded += &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt;(workflowRuntime_WorkflowUnloaded);&lt;BR&gt;&amp;nbsp;&amp;nbsp; workflowRuntime.WorkflowPersisted += &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;EventHandler&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;gt;(workflowRuntime_WorkflowPersisted);&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;...&lt;BR&gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; workflowRuntime_WorkflowPersisted(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Persisted {0} on {1}"&lt;/FONT&gt;&lt;FONT size=2&gt;, e.WorkflowInstance.InstanceId, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Now.ToUniversalTime());&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; workflowRuntime_WorkflowUnloaded(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Unloaded {0} on {1}"&lt;/FONT&gt;&lt;FONT size=2&gt;, e.WorkflowInstance.InstanceId, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Now.ToUniversalTime());&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; workflowRuntime_WorkflowLoaded(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Loaded {0} on {1}"&lt;/FONT&gt;&lt;FONT size=2&gt;, e.WorkflowInstance.InstanceId, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Now.ToUniversalTime());&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#000000&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; workflowRuntime_WorkflowIdled(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; sender, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;WorkflowEventArgs&lt;/FONT&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Idled {0} on {1}"&lt;/FONT&gt;&lt;FONT size=2&gt;, e.WorkflowInstance.InstanceId, &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;DateTime&lt;/FONT&gt;&lt;FONT size=2&gt;.Now.ToUniversalTime());&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;
&lt;P&gt;Before we press the magic F5 button, there's one more thing to do. Go to &lt;STRONG&gt;SQL Server Management Studio Express&lt;/STRONG&gt; and create a new query:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;use&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; SqlPersistenceDemo&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;exec&lt;/FONT&gt;&lt;FONT size=2&gt; dbo&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;RetrieveAllInstanceDescriptions&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;select&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;*&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;from&lt;/FONT&gt;&lt;FONT size=2&gt; dbo&lt;/FONT&gt;&lt;FONT color=#808080 size=2&gt;.&lt;/FONT&gt;&lt;FONT size=2&gt;InstanceState&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;Basically, the two are almost identical. Generally, I'd recommend to rely on the stored procedures to retrieve information about the workflow instances in progress, but let's just illustrate both:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo10.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Now, run the workflow application. You'll see something like this:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo11.jpg"&gt;&lt;/P&gt;
&lt;P&gt;As you can see, the idled event is followed by unloading the workflow, thanks to the persistence service (cf. the second "unloadOnIdle" parameter in the constructor call of SqlPersistenceService). Next, when the workflow is unloaded, it's time to persist the workflow instance in the database. While the application is running you have 10 seconds to re-run the query to see this:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo13.jpg"&gt;&lt;/P&gt;
&lt;P&gt;If you want to understand how a workflow is persisted, check out the Windows SDK documentation on writing a custom persistence service (search for "&lt;SPAN id=nsrTitle&gt;Creating Custom Persistence Services&lt;/SPAN&gt;"). All of this works using serialization of the runtime workflow instance state.&lt;/P&gt;
&lt;P&gt;Finally, the workflow will be reloaded and execution continues:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/persistencedemo12.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Notice execution didn't proceed after 10 seconds, but it took 15 seconds instead. The reason for this is the specified loading interval (cf. last parameter to the SqlPersistenceService constructor parameter). Based on this interval, the runtime checks whether a timer has expired amongst the persisted workflow instances.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Tip:&lt;/STRONG&gt; Lower the delay's TimeoutDuration to 9 seconds and see what happens. Keep in mind little delays incurred by the runtime to do the persistence when&amp;nbsp;analyzing the results.&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In this post, we've seen the basics of the workflow state persistence services. Thanks to this service, long-running workflows can be implemented efficiently without you having to worry much about the persistence itself. In other words, services like persistence services free developers from the burden to cope with error-prone tasks and recurring patterns like implementing persistence. In the next workflow post, I'll focus on the tracking service, so keep an eye on my RSS feed.&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4580" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Workflow+Foundation+_2800_WF_2900_/default.aspx">Windows Workflow Foundation (WF)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>.NET Framework 3.0 September CTP</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/09/24/4484.aspx</link><pubDate>Mon, 25 Sep 2006 05:19:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4484</guid><dc:creator>bart</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4484</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/09/24/4484.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial size=2&gt;Short no-nonsense post: &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6636e90-26e6-44e0-8780-5d3ccd3d94ed&amp;amp;DisplayLang=en"&gt;here it is&lt;/A&gt;. Associated tools can be found in the Related Resources section of the page. For the Belgians reading this blog: cu tomorrow in Brussels for the .NET Framework 3.0 event (house fully booked).&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;Cheers!&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4484" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category></item><item><title>Creating a WCF POP3 tunnel - Part 3 - A look on the client-side</title><link>http://community.bartdesmet.net/blogs/bart/archive/2006/09/15/4420.aspx</link><pubDate>Fri, 15 Sep 2006 07:21:00 GMT</pubDate><guid isPermaLink="false">863c5522-913f-4a64-ac0a-bd5f05abad0f:4420</guid><dc:creator>bart</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://community.bartdesmet.net/blogs/bart/rsscomments.aspx?PostID=4420</wfw:commentRss><comments>http://community.bartdesmet.net/blogs/bart/archive/2006/09/15/4420.aspx#comments</comments><description>&lt;P&gt;&lt;FONT face=Arial color=#000080&gt;&lt;STRONG&gt;Introduction&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;In the &lt;A HREF="/blogs/bart/archive/2006/09/12/4416.aspx"&gt;introductory post&lt;/A&gt; of this blog series, I explained our mission statement: the creation of a POP3 tunnel over SOAP/HTTP using WCF. The first part of the implementation was covered in &lt;A HREF="/blogs/bart/archive/2006/09/13/4417.aspx"&gt;part 1&lt;/A&gt; of this blog series: "A simple POP3 client in C#". In &lt;A HREF="/blogs/bart/archive/2006/09/14/4418.aspx"&gt;part&amp;nbsp;2&lt;/A&gt; we exposed the POP3 client&amp;nbsp;using a WCF service. In this &lt;STRONG&gt;final episode&lt;/STRONG&gt;, we leave the server side and enter the scene of the &lt;STRONG&gt;client&lt;/STRONG&gt;, where we need a WCF client as well as a little local POP3 server to capture POP3 commands and translate these into calls to the WCF service. This realizes our SOAP-based and firewall-friendly tunnel.&lt;/FONT&gt;&lt;FONT face=Arial size=2&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Where are we?&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;The diagram below &lt;FONT color=#ff0000&gt;shows the piece of the solution we'll be focusing on&lt;/FONT&gt; in this post:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#006400 size=2&gt;&lt;FONT color=#000000&gt;********************LOCALHOST*******************&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;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; &lt;FONT color=#808080&gt;+-------------+&lt;/FONT&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; &lt;FONT color=#ff0000&gt;+-------------+&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; &lt;FONT color=#808080&gt;| Mail client | -(TCP:110)-&amp;gt;&lt;/FONT&gt; &lt;FONT color=#ff0000&gt;| POP3 server |&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; &lt;FONT color=#808080&gt;+-------------+&lt;/FONT&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; &lt;FONT color=#ff0000&gt;+------+------+&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#ff0000&gt;|&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#ff0000&gt;+------+------+&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#ff0000&gt;| WCF client&amp;nbsp; |&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#ff0000&gt;+------+------+&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#ff0000&gt;|&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;**************************************&lt;/FONT&gt;&lt;FONT color=#ff0000&gt;|&lt;/FONT&gt;&lt;FONT color=#000000&gt;*********&lt;BR&gt;&lt;/FONT&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; &lt;FONT color=#ff0000&gt;|&lt;/FONT&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; &lt;FONT color=#ff0000&gt;(HTTP/SOAP:80)&lt;/FONT&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; &lt;FONT color=#0000ff&gt;|&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;******************TUNNEL SERVER*******&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;|&lt;/FONT&gt;&lt;FONT color=#000000&gt;*********&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#0000ff&gt;|&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;+--------------+&lt;/FONT&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 color=#0000ff&gt;+------+------+&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;| POP3 client&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;+-----&amp;lt;==-----+ WCF server&amp;nbsp; |&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;+------+-------+&lt;/FONT&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 color=#0000ff&gt;+-------------+&lt;/FONT&gt; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;|&lt;/FONT&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; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*********&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;|&lt;/FONT&gt;&lt;FONT color=#000000&gt;**************************************&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#808080&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;|&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#0000ff&gt;(TCP:110)&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; |&lt;BR&gt;&lt;FONT color=#000000&gt;*********&lt;/FONT&gt;|&lt;FONT color=#000000&gt;********TARGET SERVER*****************&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&gt; | POP3 server&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 color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&gt;*&lt;/FONT&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; &lt;FONT color=#000000&gt;*&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#000000&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;BR&gt;&lt;/FONT&gt;&lt;FONT color=#000000&gt;************************************************&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;&lt;U&gt;Legend:&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;FONT color=#808080&gt;Gray&lt;/FONT&gt;&amp;nbsp; - External components&lt;BR&gt;&lt;FONT color=#0000ff&gt;Blue&lt;/FONT&gt;&amp;nbsp; - Implemented in previous posts&lt;BR&gt;&lt;FONT color=#ff0000&gt;Red&lt;/FONT&gt;&amp;nbsp;&amp;nbsp; - Covered in this post&lt;BR&gt;&lt;FONT color=#006400&gt;Green&lt;/FONT&gt; - To be covered in further posts&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face="Courier New"&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;A WCF service proxy&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;On the client-side, we need two things: a &lt;STRONG&gt;POP3 server&lt;/STRONG&gt; and a &lt;STRONG&gt;WCF service client&lt;/STRONG&gt;. To keep things easy, we'll host these two in a simple Console Application.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;If we want to talk to our WCF service, we'll need a service proxy on the client-side. So, let's kick off by generating one using the Visual Studio 2005 built-in support that's added by the .NET Framework 3.0 tool support setup. To do this, go to the Solution Explorer, right click the project node and choose "&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Add Service Reference&lt;/FONT&gt;&lt;/STRONG&gt;" as depicted below:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;&lt;/FONT&gt;&lt;IMG src="http://www.bartdesmet.net/images/wcfpop3_06.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;In order to do this, make sure you're running the WCF service host application we built in &lt;A HREF="/blogs/bart/archive/2006/09/14/4418.aspx"&gt;part 2&lt;/A&gt;. Also make sure the address of the service is spelled correctly to reflect the address you've chosen when implementing the &lt;A HREF="/blogs/bart/archive/2006/09/14/4418.aspx"&gt;part 2&lt;/A&gt; stuff (normally it should be just fine as it is).&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;A lightweight POP3 server&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Time to start the implementation effort for the &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;POP3 server&lt;/FONT&gt;&lt;/STRONG&gt;. This lightweight POP3 server will run on the client's machine and take in all POP3 commands that have to be sent to the real target POP3 server. Instead of having the mail client talk to the target POP3 server directly (e.g. foo.mydomain.local:110) we'll make the mail client talk to localhost:110 instead. The POP3 server on the local machine will then establish a session with the target POP3 server by calling the Connect method first (e.g. Connect("foo.mydomain.local", 110)):&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;Mail client software connects to localhost:110.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;Local POP3 server connects to the WCF service and sends Connect("foo.mydomain.local", 110) - this establishes a session on the WCF service.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;WCF service establishes a connection with the target POP3 server "foo.mydomain.local".&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;From this point on, POP3 commands can flow between the mail client software and the target POP3 server using the HTTP/SOAP tunnel.&lt;/FONT&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;Mail client software sends "USER bart" to localhost:110.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;Local POP3 server receives the "USER bart" command and parses it in order to make a User("Bart") call on the WCF service.&lt;/FONT&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;FONT face=Arial&gt;WCF service rebuilds the original "USER bart" call upon receiving the User("Bart") method call and sends it to the target POP3 server "foo.mydomain.local".&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Let's start with the beginning: the &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;class skeleton&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT color=#000000&gt;:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;Pop3Server&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;TcpListener&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; listener;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Thread&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; tListener;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; url;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; Pop3Server(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;FONT size=2&gt; port, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; url)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; listener = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;TcpListener&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;IPAddress&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.Loopback, port);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.url = url;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Next, add two methods to &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;start &lt;/STRONG&gt;and&lt;STRONG&gt; stop&lt;/STRONG&gt;&lt;/FONT&gt; the local POP3 server:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face=Arial&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Start()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; listener.Start();&lt;BR&gt;&amp;nbsp;&amp;nbsp; tListener = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Thread&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ThreadStart&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;(Listen));&lt;BR&gt;&amp;nbsp;&amp;nbsp; tListener.Start();&lt;BR&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;public&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Stop()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; tListener.Abort();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; while&lt;/FONT&gt;&lt;FONT size=2&gt; (tListener.ThreadState != &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ThreadState&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;.Aborted)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;BR&gt;&amp;nbsp;&amp;nbsp; listener.Stop();&lt;BR&gt;}&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;To do this, we just use some quick-n-dirty threading stuff. A cleaner approach can be taken to stop the server more smoothly in order to close communications with the server in a friendly way. However, for demonstration purposes this approach should be okay. Here's the Listen method that acts as the server's background &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;listening thread&lt;/FONT&gt;&lt;/STRONG&gt;:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Listen()&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; while&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TcpClient&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; client = listener.AcceptTcpClient();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Thread&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ParameterizedThreadStart&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;(StartSession)).Start(client);&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;Basically, this method sits and wait for incoming client connections (i.e. connections made from the mail client software to localhost:110). When a connection is made, a &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;background session thread &lt;/FONT&gt;&lt;/STRONG&gt;is started, passing in the TcpClient object as a parameter through the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.threading.parameterizedthreadstart.aspx"&gt;ParameterizedThreadStart delegate&lt;/A&gt;&amp;nbsp;(new in .NET 2.0):&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; StartSession(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; state)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp; TcpClient&lt;/FONT&gt;&lt;FONT size=2&gt; client = state &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;as&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;TcpClient&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt; (client != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Pop3Session&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;(client).Start();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;Time has come to start the real work: the &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;Pop3Session class&lt;/FONT&gt;&lt;/STRONG&gt;. I've declared this class as a nested private class inside the Pop3Server class. Let's start by examining the class' skeleton:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;Pop3Session&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;const&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; server = &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"foo.mydomain.local"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;const&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; port = 110;&lt;BR&gt;&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ASCIIEncoding&lt;/FONT&gt;&lt;FONT size=2&gt; encoding = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;ASCIIEncoding&lt;/FONT&gt;&lt;FONT size=2&gt;();&lt;/FONT&gt;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;NetworkStream&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; stream;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;StreamReader&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; sr;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; localhost.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Pop3TunnelServiceClient&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; svc;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; public&lt;/FONT&gt;&lt;FONT size=2&gt; Pop3Session(&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;TcpClient&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; client)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.stream = client.GetStream();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this&lt;/FONT&gt;&lt;FONT size=2&gt;.sr = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;StreamReader&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;(stream);&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; svc = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; localhost.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Pop3TunnelServiceClient&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;();&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Notice that we've hardcoded the target server and port that we want our WCF service session to connect to. In reality, you'll obtain this information through configuration (app.config, the registry, whatever you want) and maybe pass it to the Pop3Session from the Pop3Server upon creation of a session.&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;Basically, this class has two faces. The first one is the TCP socket one, supported by the &lt;EM&gt;stream&lt;/EM&gt; member. The second one is the WCF client one, supported by the &lt;EM&gt;svc&lt;/EM&gt; proxy instance. As long as the local POP3 session lasts, the WCF service session keeps alive too.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;On to the &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;Start method&lt;/STRONG&gt; &lt;/FONT&gt;which contains the main loop that waits for commands sent by the local mail client software to the localhost:110 local POP3 server:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; Start()&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; result = svc.Connect(server, port);&lt;BR&gt;&amp;nbsp;&amp;nbsp; Write(result);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#000000&gt;&lt;BR&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;for&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (; ; )&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (!ExecuteCommand(sr.ReadLine()))&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp; sr.Close();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; stream.Close();&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;The first thing the Start method does (which is - for the record - called on a separate thread by the Pop3Server's Listen connection listening loop) is connecting to the target server by calling the svc.&lt;STRONG&gt;Connect&lt;/STRONG&gt; method. This method starts a WCF session; recall the WCF service contract defined in &lt;A HREF="/blogs/bart/archive/2006/09/14/4418.aspx"&gt;part 2&lt;/A&gt;:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; [&lt;FONT color=#008080 size=2&gt;OperationContract&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;U&gt;&lt;STRONG&gt;IsInitiating&lt;/STRONG&gt; &lt;STRONG&gt;= &lt;/STRONG&gt;&lt;/U&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;STRONG&gt;&lt;U&gt;true&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;)]&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; string&lt;/FONT&gt;&lt;FONT size=2&gt; Connect(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; server, &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; port);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;Next, we start to wait for POP3 commands sent by the local mail client. POP3 commands are straightforward to take in because they come in as single-line strings, terminated by a CRLF (\r\n) pair. Therefore, the ReadLine method of the StreamReader attached to the NetworkStream will just do its job fine.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;Every command is then forwarded to the &lt;FONT color=#ff0000&gt;&lt;STRONG&gt;ExecuteCommand&lt;/STRONG&gt; helper method&lt;/FONT&gt;, defined below:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;bool&lt;/FONT&gt;&lt;FONT size=2&gt; ExecuteCommand(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; command)&lt;BR&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt; (command == &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; || command.Length &amp;lt; 3)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; string&lt;/FONT&gt;&lt;FONT size=2&gt;[] cmds = command.Split(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;' '&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (cmds.Length == 0)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; switch&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (cmds[0].ToUpper())&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"USER"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; (cmds.Length != 2)&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt;&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;Write(svc.User(cmds[1]));&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"PASS"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; (cmds.Length != 2)&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(svc.Pass(cmds[1]));&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"STAT"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; (cmds.Length != 1)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(svc.Stat());&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"LIST"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; (cmds.Length &amp;gt; 2)&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; (cmds.Length == 1)&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(svc.List());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;else&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&amp;nbsp;&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; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; msg;&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&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;if&lt;/FONT&gt;&lt;FONT size=2&gt; (!&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;.TryParse(cmds[1], &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; msg))&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(svc.List2(msg));&lt;BR&gt;&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 size=2&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"DELE"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length != 2)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&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;if&lt;/FONT&gt;&lt;FONT size=2&gt; (!&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;.TryParse(cmds[1], &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg))&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&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; Write(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;svc.Dele(msg));&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"RETR"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length != 2)&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; &lt;/FONT&gt;&lt;FONT face="Courier New"&gt;SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&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;uint&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt; (!&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;.TryParse(cmds[1], &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg))&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&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; Write(&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;svc.Retr(msg));&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&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;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"TOP"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length != 3)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&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; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; n;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt; (!&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;.TryParse(cmds[1], &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;FONT size=2&gt; msg) || !&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;.TryParse(cmds[2], &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; n))&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&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; Write(svc.Top(msg, n));&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;}&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&lt;FONT color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"QUIT"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length != 1)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(svc.Quit());&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&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; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"RSET"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length != 1)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&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;Write(svc.Rset())&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"UIDL"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length &amp;gt; 2)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length == 1)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&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&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;Write(svc.Uidl());&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; uint&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if&lt;/FONT&gt;&lt;FONT size=2&gt; (!&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;uint&lt;/FONT&gt;&lt;FONT size=2&gt;.TryParse(cmds[1], &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;out&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; msg))&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&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; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&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; Write(svc.Uidl2(msg));&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"APOP"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;:&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt; (cmds.Length != 3)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendError();&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Write(svc.Apop(cmds[1], cmds[2]));&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; return&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;; &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;Again, I've omitted all Console.Write* stuff that prints diagnostic information on the screen. This ExecuteCommand method should be very easy to understand. It performs some basic parsing of the command that's received by our local POP3 server and calls the appropriate method on the WCF service through the svc proxy instance. Two &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;helper methods&lt;/FONT&gt;&lt;/STRONG&gt; are required:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;private&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; SendError()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; Write(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"-ERR Protocol error."&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; Write(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; msg)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#0000ff&gt;string &lt;/FONT&gt;s = msg + &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"\r\n"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; byte&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;[] b = encoding.GetBytes(s.ToCharArray());&lt;BR&gt;&amp;nbsp;&amp;nbsp; stream.Write(b, 0, b.Length);&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;As you recall from the service contract, every POP3 equivalent web method takes in all of the parameters required for that command and returns the POP3 response string that was obtained by the target POP3 server. Using the Write method this answer is sent back to the local mail client, with the trailing CRLF pair:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp; Write(svc.User(cmds[1]));&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;In order to run this client, we need some simple &lt;STRONG&gt;&lt;FONT color=#ff0000&gt;host&lt;/FONT&gt;&lt;/STRONG&gt; code (read: a Main method):&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" color=#008080 size=2&gt;Program&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; Main(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;[] args)&lt;BR&gt;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt; port = 110;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string&lt;/FONT&gt;&lt;FONT size=2&gt; url = &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;new&lt;/FONT&gt;&lt;FONT size=2&gt; BdsSoft.Net.Mail.localhost.&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Pop3TunnelServiceClient&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;().Endpoint.Address.Uri.ToString();&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"WCF POP3 Tunnel Client"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"======================"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.WriteLine();&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"Initializing local tunnel endpoint..."&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"- Local POP3 server listening on TCP port {0}"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;, port);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;FONT size=2&gt;.WriteLine(&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"- Forwarding to {0}"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;, url);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;.WriteLine();&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Pop3Server&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;(port, url).Start();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT face="Courier New"&gt;.ReadLine();&lt;BR&gt;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Configuration&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Last but not least, our client needs some configuration. The WCF "Add Service Dialog" will have added an app.config file already but it requires some changes, as shown below. These changes are required to deal with large responses, e.g. in response to a RETR POP3 command that retrieves an entire mail message (the default of 16 KB is not sufficient for our purposes). If you decide to implement this stuff for production purposes, you'll want to change the endpoint address to some remote server of course, not just the local machine which we are using for demo purposes (&lt;EM&gt;tunnel server and localhost are the same machine&lt;/EM&gt;).&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&amp;lt;?&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#800000 size=2&gt;xml&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;encoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;utf-8&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt; ?&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;configuration&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;system.serviceModel&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;bindings&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WSHttpBinding_IPop3TunnelService&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;closeTimeout&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;00:01:00&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;openTimeout&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;00:01:00&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;receiveTimeout&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;00:10:00&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;sendTimeout&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;00:01:00&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;bypassProxyOnLocal&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;transactionFlow&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;hostNameComparisonMode&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;StrongWildcard&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;maxBufferPoolSize&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;524288&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#ff0000 size=2&gt;maxReceivedMessageSize&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;2147483647&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;STRONG&gt;&lt;U&gt;"&lt;BR&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;messageEncoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Text&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;textEncoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;utf-8&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;useDefaultWebProxy&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;allowCookies&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;readerQuotas&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;maxDepth&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;32&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;STRONG&gt;&lt;U&gt;&lt;FONT color=#ff0000 size=2&gt;maxStringContentLength&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;2147483647&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;maxArrayLength&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;16384&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;maxBytesPerRead&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;4096&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;maxNameTableCharCount&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;16384&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;reliableSession&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;ordered&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;inactivityTimeout&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;00:10:00&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;enabled&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;false&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;security&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;mode&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Message&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;transport&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;clientCredentialType&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Windows&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;proxyCredentialType&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;None&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;realm&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;""&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;message&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;clientCredentialType&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Windows&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;negotiateServiceCredential&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&lt;FONT color=#0000ff&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; &lt;/FONT&gt;algorithmSuite&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Default&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;establishSecurityContext&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;true&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;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;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;security&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;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;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;binding&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;bindings&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;client&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;endpoint&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;address&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;http://localhost:8080/BdsSoft.Net.Mail/Pop3TunnelService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; binding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wsHttpBinding&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;bindingConfiguration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WSHttpBinding_IPop3TunnelService&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; contract&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;BdsSoft.Net.Mail.localhost.IPop3TunnelService&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;WSHttpBinding_IPop3TunnelService&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;identity&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;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;lt;&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;userPrincipalName&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;value&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;EM&gt;something&lt;/EM&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;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;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;identity&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;endpoint&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;client&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;system.serviceModel&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT size=2&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Take it to the test&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Right, let's try it. Make sure the target server and port are set correctly (i.e. to some POP3 server you have a mailbox on) in the Pop3Session class:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;const&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;string&lt;/FONT&gt;&lt;FONT size=2&gt; server = &lt;/FONT&gt;&lt;FONT color=#800000 size=2&gt;"foo.mydomain.local"&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp; private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;const&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;int&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt; port = 110;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Next, make sure the WCF service from &lt;A HREF="/blogs/bart/archive/2006/09/14/4418.aspx"&gt;part 2&lt;/A&gt;&amp;nbsp;is up and running. When the server-side has started, you can launch the client-side tool we've been creating in this episode:&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/wcfpop3_07.jpg"&gt;&lt;/P&gt;
&lt;P&gt;Now configure your mail client software to connect to the local POP3 server (you can set the SMTP server to whatever server you want, we won't send mail for now):&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/wcfpop3_09.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;U&gt;&lt;STRONG&gt;Tip:&lt;/STRONG&gt;&lt;/U&gt; For testing purposes, I recommend to check the "Leave a copy of messages on server" checkbox, to avoid loosing mail.&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/wcfpop3_10.jpg"&gt;&lt;/P&gt;
&lt;P&gt;You should see some result like this &lt;FONT color=#ff0000&gt;if you add some logging code to the client and server applications&lt;/FONT&gt; (note: the code that's available for download has this kind of logging code):&lt;/P&gt;
&lt;P&gt;&lt;IMG src="http://www.bartdesmet.net/images/wcfpop3_08.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Download the code&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;You can download the code for the client-side implementation of the POP3 server and WCF client &lt;A href="http://www.bartdesmet.net/download/wcfpop3client.zip"&gt;&lt;STRONG&gt;&lt;FONT color=#006bad&gt;over here&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/A&gt;. Make sure to check out&amp;nbsp;&lt;A HREF="/blogs/bart/archive/2006/09/13/4417.aspx"&gt;part 1&lt;/A&gt;&amp;nbsp;and &lt;A HREF="/blogs/bart/archive/2006/09/14/4418.aspx"&gt;part 2&lt;/A&gt;&amp;nbsp;of this series to download the associated server-side code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial size=2&gt;&lt;FONT color=#ff0000&gt;All usual disclaimers apply.&amp;nbsp;The writer of this blog doesn't make any warranties or guarantuees about the quality of this software, and isn't responsible for possible information loss under any circumstance whatsoever. The code on this blog post and in the download&amp;nbsp;are made available&amp;nbsp;for demonstration purposes only.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial color=#000080 size=3&gt;&lt;STRONG&gt;Conclusion&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Arial&gt;Using WCF it's fairly easy to create a HTTP/SOAP tunnel for an older protocol such as POP3. It won't be difficult at all to tunnel protocols like SMTP and IMAP4 too, although every protocol has its own characteristics and implementation complexities. Luckily, POP3 is a pretty simple protocol that allowed me to illustrate you the principle of all this beauty with a relatively small amount of code.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Time to tunnel?&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://community.bartdesmet.net/aggbug.aspx?PostID=4420" width="1" height="1"&gt;</description><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/.NET+Framework+3.0+_2800_WinFX_2900_/default.aspx">.NET Framework 3.0 (WinFX)</category><category domain="http://community.bartdesmet.net/blogs/bart/archive/tags/Windows+Communication+Foundation+_2800_WCF_2900_/default.aspx">Windows Communication Foundation (WCF)</category></item></channel></rss>