<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>gordonhogenson</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/gordonhogenson/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:20:41 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Installing Azure SDK 2.3 for Visual Studio "14" CTP</title>
      <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/installing-azure-sdk-2-3-for-visual-studio-14-ctp</link>
      <pubDate>Mon, 02 Jun 2014 17:58:00 GMT</pubDate>
      <dc:creator><![CDATA[GordonHogenson1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gordonhogenson/2014/06/02/installing-azure-sdk-2-3-for-visual-studio-14-ctp/</guid>
      <description><![CDATA[To install the Azure SDK 2.3 for .NET with Visual Studio "14" CTP, follow these steps. This...]]></description>
      <content:encoded><![CDATA[<p style="border-width: 0px; margin: 10px 0px 15px; padding: 0px;">To install the Azure SDK 2.3 for .NET with Visual Studio "14" CTP, follow these steps. This procedure installs SDKs, basic tools, and extended tools for Azure development with Visual Studio "14" CTP and is not intended to be used with any other version of Visual Studio.</p>
<p style="border-width: 0px; margin: 15px 0px; padding: 0px;">To install the Azure SDK 2.3 for .NET, follow these steps:</p>
<ol style="border-width: 0px; padding: 0px 0px 0px 30px; margin-top: 15px; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px;">
<li style="border-width: 0px; margin: 0px; padding: 0px;">Install<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400850">Visual Studio "14" CTP</a><span class="Apple-converted-space">&nbsp;</span>on a machine without any other version of Visual Studio installed.</li>
<li style="border-width: 0px; margin: 0px; padding: 0px;">
<p style="border-width: 0px; margin: 0px 0px 15px; padding: 0px;">Install each component of the Azure SDK using the links in the following list, in this order. Choose the x86 or x64 version of each of the following components.</p>
<ul style="border-width: 0px; margin: 0px; padding: 0px 0px 0px 30px;">
<li style="border-width: 0px; margin: 0px; padding: 0px;">Azure authoring tools:<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400892">WindowsAzureAuthoringTools-x86.msi</a><span class="Apple-converted-space">&nbsp;</span>or<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400893">WindowsAzureAuthoringTools-x64.msi</a>.</li>
<li style="border-width: 0px; margin: 0px; padding: 0px;">Azure compute emulator:<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400894">WindowsAzureEmulator-x86.exe</a><span class="Apple-converted-space">&nbsp;</span>or <a href="https://go.microsoft.com/fwlink/p/?LinkId=400895">WindowsAzureEmulator-x64.exe</a>.</li>
<li style="border-width: 0px; margin: 0px; padding: 0px;">The Azure client libraries:<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400896">WindowsAzureLibsForNet-x86.msi</a>&nbsp;or<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400897">WindowsAzureLibsForNet-x64.msi</a>.</li>
<li style="border-width: 0px; margin: 0px; padding: 0px;">The storage emulator:<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400904">WindowsAzureStorageEmulator.msi</a>. If you receive a warning regarding local SQL databases, install SQL Server LocalDB 11.0 from<span class="Apple-converted-space">&nbsp;</span><a href="https://go.microsoft.com/fwlink/p/?LinkId=400778">this location</a><span class="Apple-converted-space">&nbsp;</span>for x86 or <a href="https://go.microsoft.com/fwlink/p/?LinkId=400779">this location</a><span class="Apple-converted-space">&nbsp;</span>for x64.</li>
<li style="border-width: 0px; margin: 0px; padding: 0px;">Azure Tools for Visual Studio: <a href="https://go.microsoft.com/fwlink/p/?LinkId=400903">WindowsAzureTools.vs140.exe</a>.</li>
</ul>
</li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>Using MailboxProcessor.Scan for communication between F# agents</title>
      <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/using-mailboxprocessor-scan-for-communication-between-f-agents</link>
      <pubDate>Thu, 20 Jan 2011 18:14:00 GMT</pubDate>
      <dc:creator><![CDATA[GordonHogenson1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gordonhogenson/2011/01/20/using-mailboxprocessor-scan-for-communication-between-f-agents/</guid>
      <description><![CDATA[In a previous post, I presented a background job manager in F# using the MailboxProcessor.&nbsp; In...]]></description>
      <content:encoded><![CDATA[<p>In a <a href="https://blogs.msdn.com/b/gordonhogenson/archive/2011/01/14/using-f-agents-to-manage-background-jobs-with-cancellation.aspx" title="previous post">previous post</a>, I presented a background job manager in F# using the <a href="https://msdn.microsoft.com/en-us/library/ee370357.aspx" title="MailboxProcessor">MailboxProcessor</a>.&nbsp; In this post, I'll try to keep the number of background jobs equal to the number of processors on the machine.&nbsp; The number of processors that is meaningful here is the number of CPUs in the machine times the number of cores in each CPU.&nbsp; On my system, there are only two, but newer or more high-end machines have many cores, perhaps 4, 8, or 16.</p>
<p>With these advances in hardware, obviously you want to make as efficient use as possible of all the cores on the machine.&nbsp; Let's imagine that you have a series of long computations to do, and you want to maximize the use of CPU.&nbsp; One way to do this is to use F# agents, namely the <strong>MailboxProcessor</strong> class, to manage these computations as jobs.&nbsp; An F# agent is something that processes messages in a queue.&nbsp; </p>
<p>To manage these background jobs, I created an F# agent called <strong>controllerAgent</strong> that accepts requests for jobs to be run.&nbsp; I then created an array of agents equal to the number of processors on the machine.&nbsp; The .NET Framework provides the property <strong>Environment.ProcessorCount</strong> which conveniently gives you this.</p>
<p>In this example, the computation is one I used in a previous blog entry, computing the <em>N</em>th prime number.&nbsp; You will no doubt be able to come up with a more efficient algorithm for doing this (<a href="https://fsharpnews.blogspot.com/2010/02/sieve-of-eratosthenes.html" title="such as this one by Jon Harrop">such as this one by Jon Harrop</a>), but since I'm just trying to show how to run a computation and view its result, this will do fine.&nbsp; </p>
<p>In this example, the array of agents that represent each processor is&nbsp;called &nbsp;<strong>execAgents</strong>.&nbsp; Initially, I created it as an array of nulls.&nbsp; This is because its initialization code uses the <strong>controllerAgent</strong>.&nbsp; What I have here are mutually self-referential entities.&nbsp; In F#, definitions of a value must precede the use of&nbsp;the value.&nbsp; By defining the <strong>execAgents</strong> array first, I can reference it in the initialization code for <strong>controllerAgent</strong>.</p>
<p>In previous blog posts, I used <strong>Receive</strong> to process each message.&nbsp; In this example, I use <strong>Scan</strong>.&nbsp; <strong>Scan</strong> allows me to look through the queue for the appropriate type of message.&nbsp; The standard use of <strong>Scan</strong> is with cooperative agents.&nbsp; Agent A is processing messages, but needs some help from agent B, so it sends a&nbsp;message to agent B.&nbsp; Agent B replies, and agent A uses <strong>Scan</strong> to find the reply.&nbsp; In this example, the <strong>controllerAgent</strong> processes the messages and signals the <strong>execAgent</strong> to start a job, but if all the <strong>execAgents</strong> are busy, it waits for a message from an <strong>execAgent</strong> saying it has completed a job.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: green;">// Assume we have n processors on a machine and always want 1 job running per processor.</span></p>
<p style="margin: 0px;"><span style="color: green;">// A set of agents represent processors, which can be either busy or idle.</span></p>
<p style="margin: 0px;"><span style="color: green;">// The controller accepts requests and assigns the job to one of the processor queues.</span></p>
<p style="margin: 0px;"><span style="color: green;">// The main processor keeps track of whether each node is busy or idle.&nbsp; If one is idle,</span></p>
<p style="margin: 0px;"><span style="color: green;">// the job is assigned immediately.&nbsp; If there is no idle processor, the message box is scanned</span></p>
<p style="margin: 0px;"><span style="color: green;">// until a message is found indicating a job was completed.</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> numProcs = Environment.ProcessorCount</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">type</span> Job&lt;'Result&gt; = int&nbsp; * Async&lt;'Result&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: green;">// Request to run a job, or</span></p>
<p style="margin: 0px;"><span style="color: green;">// completed notification (with proc&nbsp;ID and jobId)</span></p>
<p style="margin: 0px;"><span style="color: blue;">type</span> RequestMessage&lt;'Result&gt; = </p>
<p style="margin: 0px;">&nbsp;&nbsp; | Request <span style="color: blue;">of</span> Job&lt;'Result&gt;</p>
<p style="margin: 0px;">&nbsp;&nbsp; | Completed <span style="color: blue;">of</span> int * int</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: green;">// Contains the&nbsp;ID of the processor and the job.</span></p>
<p style="margin: 0px;"><span style="color: blue;">type</span> RunMessage&lt;'Result&gt; = int * Job&lt;'Result&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> random = System.Random()</p>
<p style="margin: 0px;"><span style="color: green;">// The program computes the Nth prime numbers for various</span></p>
<p style="margin: 0px;"><span style="color: green;">// values of N.</span></p>
<p style="margin: 0px;"><span style="color: green;">// This number determines how large values of N are.</span></p>
<p style="margin: 0px;"><span style="color: blue;">let</span> multiplier = 5000</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: green;">// Generates jobs.</span></p>
<p style="margin: 0px;"><span style="color: blue;">let</span> createJob(id:int, computation, input:int) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> job = async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> result = computation(input)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; id, job</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> execAgents = Array.zeroCreate&lt;MailboxProcessor&lt;RunMessage&lt;_&gt;&gt;&gt; numProcs</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> controllerAgent = <span style="color: blue;">new</span> MailboxProcessor&lt;RequestMessage&lt;_&gt;&gt;(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// First try to identify an idle proc by calling tryFindIndex.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// If there is an idle processor, scan for a request and run it.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// If there is not an idle processor, scan for an idle notification.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// No timeout given, so scan may wait indefinitely either to receive</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// a new request, or for a processor to signal that it's idle.&nbsp; Meanwhile,</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// messages build up in the queue.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// An array indicating whether each processor is idle.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> idleStatus = Array.create numProcs <span style="color: blue;">true</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop (count) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> idleId = Array.tryFindIndex (<span style="color: blue;">fun</span> elem <span style="color: blue;">-&gt;</span> elem) idleStatus</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">match</span> idleId <span style="color: blue;">with</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Some id <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> inbox.Scan(<span style="color: blue;">function</span> | Request((jobId, _) <span style="color: blue;">as</span> job) <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Some(async { </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; idleStatus.[id] &lt;- <span style="color: blue;">false</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Job #%d submitted."</span> jobId</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; execAgents.[id].Post(id, job) })</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Completed _ <span style="color: blue;">-&gt;</span> None)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | None <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> inbox.Scan(<span style="color: blue;">function</span> | Request _ <span style="color: blue;">-&gt;</span> None</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Completed (id, jobId) <span style="color: blue;">-&gt;</span> </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Some(async { idleStatus.[id] &lt;- <span style="color: blue;">true</span> }))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (count + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop 0)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">for</span> procId <span style="color: blue;">in</span> 0 .. numProcs - 1 <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; execAgents.[procId] &lt;- <span style="color: blue;">new</span> MailboxProcessor&lt;RunMessage&lt;_&gt;&gt;(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop (count) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> procId, (jobId, job) = inbox.Receive()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Start the job</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Post to the controller inbox when complete.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printfn <span style="color: maroon;">"Job #%d started on procId %d."</span> jobId procId</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Async.Start(async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> result = job</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Job #%d completed."</span> jobId</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Nth Prime for N = %d is %s."</span> (multiplier*jobId) (result.ToString())</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; controllerAgent.Post(Completed(procId, jobId))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; })</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (count + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop 0)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; execAgents.[procId].Start()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">controllerAgent.Start()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> numJobs = 10</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">printfn <span style="color: maroon;">"Number Of Logical Processors: %d"</span> numProcs</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> isprime number = number &gt; 1 &amp;&amp; Seq.forall (<span style="color: blue;">fun</span> n <span style="color: blue;">-&gt;</span> number % n &lt;&gt; 0) { 2 .. number/2 }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> nthPrime n = Seq.initInfinite (<span style="color: blue;">fun</span> n <span style="color: blue;">-&gt;</span> n) </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; |&gt; Seq.filter (<span style="color: blue;">fun</span> n <span style="color: blue;">-&gt;</span> isprime n)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; |&gt; Seq.nth (n - 1)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;"><span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop (count) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> jobId = (numJobs - count)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> job = createJob(jobId, (<span style="color: blue;">fun</span> n <span style="color: blue;">-&gt;</span> nthPrime(n)), multiplier * jobId )</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Requesting job #%d"</span> jobId</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; controllerAgent.Post(Request(job))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// Delay</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; System.Threading.Thread.Sleep(1000);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">match</span> count <span style="color: blue;">with</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; | 0 <span style="color: blue;">-&gt;</span> ()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; | _ <span style="color: blue;">-&gt;</span> loop (count - 1)</p>
<p style="margin: 0px;">loop (numJobs - 1)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">printfn <span style="color: maroon;">"Done submitting jobs. Press Enter to exit when ready."</span></p>
<p style="margin: 0px;">Console.ReadLine() |&gt; ignore</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;The output shows that the number of jobs running at any given time is limited to two.</p>
<p>Number Of Logical Processors: 2<br />Requesting job #1<br />Job #1 submitted.<br />Job #1 started on procId 0.<br />Job #1 completed.<br />Nth Prime for N = 5000 is 48611.<br />Requesting job #2<br />Job #2 submitted.<br />Job #2 started on procId 1.<br />Requesting job #3<br />Job #3 submitted.<br />Job #3 started on procId 0.<br />Job #2 completed.<br />Nth Prime for N = 10000 is 104729.<br />Requesting job #4<br />Job #4 submitted.<br />Job #4 started on procId 1.<br />Requesting job #5<br />Requesting job #6<br />Job #3 completed.<br />Nth Prime for N = 15000 is 163841.<br />Job #5 submitted.<br />Job #5 started on procId 0.<br />Requesting job #7<br />Requesting job #8<br />Requesting job #9<br />Requesting job #10<br />Job #4 completed.<br />Nth Prime for N = 20000 is 224737.<br />Job #6 submitted.<br />Job #6 started on procId 1.<br />Done submitting jobs. Press Enter to exit when ready.<br />Job #5 completed.<br />Nth Prime for N = 25000 is 287117.<br />Job #7 submitted.<br />Job #7 started on procId 0.<br />Job #6 completed.<br />Nth Prime for N = 30000 is 350377.<br />Job #8 submitted.<br />Job #8 started on procId 1.<br />Job #7 completed.<br />Nth Prime for N = 35000 is 414977.<br />Job #9 submitted.<br />Job #9 started on procId 0.<br />Job #8 completed.<br />Nth Prime for N = 40000 is 479909.<br />Job #10 submitted.<br />Job #10 started on procId 1.<br />Job #9 completed.<br />Nth Prime for N = 45000 is 545747.<br />Job #10 completed.<br />Nth Prime for N = 50000 is 611953.</p>
<p>This is&nbsp;the last of this series of posts on the F# MailboxProcessor.</p>]]></content:encoded>
    </item>
    <item>
      <title>Using F# agents and cancellation tokens to manage background jobs</title>
      <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/using-f-agents-and-cancellation-tokens-to-manage-background-jobs</link>
      <pubDate>Fri, 14 Jan 2011 14:21:00 GMT</pubDate>
      <dc:creator><![CDATA[GordonHogenson1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gordonhogenson/2011/01/14/using-f-agents-and-cancellation-tokens-to-manage-background-jobs/</guid>
      <description><![CDATA[In a previous post, I created an F# agent that runs background computations.&nbsp; However, it was...]]></description>
      <content:encoded><![CDATA[<p>In a <a href="https://blogs.msdn.com/b/gordonhogenson/archive/2011/01/12/using-f-agents-to-manage-background-jobs.aspx" title="previous post">previous post</a>, I created an F# agent that runs background computations.&nbsp; However, it was limited in that it allowed the user no control over the jobs.&nbsp; Really, I want a more flexible system that allows&nbsp;the user&nbsp;to cancel currently running jobs.&nbsp; To implement this, I used F# agents (the <strong>MailboxProcessor</strong> class)&nbsp;to start jobs and to process when jobs finish.&nbsp; I implemented cancellation by keeping a collection of running jobs and using cancellation tokens, a .NET Framework 4.0 feature.&nbsp; </p>
<p>&nbsp;I created a <strong>JobState</strong> discriminated union to represent whether a job is not started,&nbsp;running, canceled or completed.&nbsp;&nbsp;</p>
<p><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// The state of the job.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> JobState =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | NotStarted</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Running</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Canceled</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Completed</span></p>
<p>&nbsp;I created a <strong>Job</strong> type that is a record.&nbsp; It includes a cancellation token, an asynchronous computation, and state information.</p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// a Job consists of a job ID, a computation, a cancellation token source,</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// and a state.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Job = {</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; id : int</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; comp : Async&lt;Result&gt;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; token : CancellationToken</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state : JobState</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p>The function to create the jobs themselves is still creating mock jobs.&nbsp; The job is represented by an asynchronous workflow, which sleeps for a while.&nbsp; But instead of one call to <strong>Sleep</strong>, it calls <strong>Sleep</strong> in a loop for a short time. At each appearance of a let!, do!,&nbsp;or other ! keyword&nbsp;(in this case, each invocation of Async.Sleep), F# checks for cancellation automatically.&nbsp; You do not have to monitor the value of <strong>IsCancellationRequsted</strong>.&nbsp; In this case, the loop is terminated when cancellation occurs,&nbsp;and if you started the job&nbsp;with&nbsp;<strong>Async.StartWithContinuations</strong>,&nbsp;then the cancellation continuation is called.&nbsp;&nbsp;</p>
<p><span style="color: green;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // Generates mock jobs using Async.Sleep</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> createJob(id:int, token:CancellationToken) =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> job = async {</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Let the time be a random number between 1 and 10000</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// And the mock computed result is a floating point value</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> time = random.Next(10000)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> result = 2.0 + random.NextDouble()</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> count = ref 0</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Start child jobs</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (!count &lt;= 100) <span style="color: blue;">do</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> Async.Sleep(time / 100)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; count := !count + 1</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> result</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { id = id; comp = job; token = token; state = JobState.NotStarted }</span></p>
<p>Cancellation is supported by the&nbsp;.NET Framework&nbsp;4.0 and involved when you&nbsp;use cancellation tokens.&nbsp;&nbsp;There are a few classes involved when using cancellation tokens.&nbsp;One class, <strong>CancellationTokenSource</strong>,&nbsp;creates a <strong>CancellationToken</strong>, which is just an identification of what you want to cancel.&nbsp;Each of these background jobs will be represented by an asynchronous work item and those work items will have an associated&nbsp;<strong>CancellationToken</strong>.&nbsp;&nbsp; The cancellation token&nbsp;is passed&nbsp;&nbsp;in as an optional argument&nbsp;when you start the jobs in the call to <strong>StartWithContinuations</strong>.</p>
<p>Cancellation tokens are really useful when you have multiple jobs that depend on each other, and you want to cancel all related jobs at once, so this example adds the ability to create child jobs.&nbsp; The child jobs all share the same cancellation token as a parent job, so they are cancelled when the parent job is cancelled.</p>
<p>Initially, I introduced a global mutable array (called jobs)&nbsp;to store information, including the&nbsp;job state, which indicates whether the job is running, canceled, etc.&nbsp;&nbsp;But, a&nbsp;global mutable value needs to have synchronized access since there&nbsp;are multiple threads writing to it.&nbsp; You can use F# agents to synchronize access to global mutable state such as a shared collection.&nbsp; I decided to try that in my job collection.&nbsp; Instead of modifying the array directly, I created&nbsp;the type&nbsp;<strong>JobCollection</strong>, and then&nbsp;I created an agent that is internal to this class,&nbsp;and I wrote a public indexed property whose setter posts to that agent when I&nbsp;modify the array.&nbsp;&nbsp;&nbsp; </p>
<p>There are three different arrays in <strong>JobCollection</strong>: one for the jobs, one for the token sources, and one for the parentIds, which is only relevant for child jobs.&nbsp; They should all have the same length.&nbsp;&nbsp;I could have&nbsp;certainly decided to put some of this in the <strong>Job</strong> type itself, but in this implementation, it's the <strong>JobCollection'</strong>s responsibility to manage parent/child relationships and make sure that the tokens in each <strong>Job</strong> come from the right token source.</p>
<p><span style="color: green;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // The&nbsp;ID of the job whose status changed and the new status.</span></span></p>
<p><span style="color: green;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp;</span></span><span style="font-family: courier new,courier;">&nbsp;<span style="color: blue;">type</span> JobStatusChangedMessage = int * JobState</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> JobCollection(numJobs) =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> tokenSources = Array.init numJobs (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> <span style="color: blue;">new</span> CancellationTokenSource())</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// The problem is that an array is mutable shared data, so all updates will be</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// managed by a jobsStatus agent.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> jobs = Array.init numJobs (<span style="color: blue;">fun</span> id <span style="color: blue;">-&gt;</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; createJob(id, tokenSources.[id].Token))</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> parentIds = Array.create numJobs None</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> jobsStatusAgent = MailboxProcessor&lt;JobStatusChangedMessage&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> jobId, jobState = inbox.Receive()</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[jobId] &lt;- { jobs.[jobId] <span style="color: blue;">with</span> state = jobState }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.Item</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">with</span> get(index) =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[index]</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">and</span> set index (value : Job) =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobsStatusAgent.Post(index, value.state)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.TokenSource <span style="color: blue;">with</span> get(index) = tokenSources.[index]</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.ParentId <span style="color: blue;">with</span> get(index) = parentIds.[index]</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.Length = jobs.Length</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Child jobs have the same CancellationToken as the parent job, so</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// if you cancel the parent job, the child jobs are also cancelled.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// This function locks the collection during these modifications.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.AddChildJobs(numJobs, parentId) =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; lock this (<span style="color: blue;">fun</span> () <span style="color: blue;">-&gt;</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> firstNewId = jobs.Length</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> newJobs = Array.init numJobs (<span style="color: blue;">fun</span> id <span style="color: blue;">-&gt;</span> createJob(firstNewId + id, jobs.[parentId].token))</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> newTokenSources = Array.create numJobs tokenSources.[parentId]</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> newParentIds = Array.create numJobs (Some(parentId))</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; jobs &lt;- Array.append jobs newJobs </span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; tokenSources &lt;- Array.append tokenSources newTokenSources</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; parentIds &lt;- Array.append parentIds newParentIds)</span></p>
<p>You could also use a lock to enforce synchronized access, as I did in the <strong>JobCollection</strong>&nbsp;method <strong>AddChildJobs</strong>.&nbsp; This method locks the collection in order to make modifications to the internal arrays.&nbsp; In a more serious implementation, it might be good to compare the performance of managed synchronized access using a lock&nbsp;to that of&nbsp;using a <strong>MailboxProcessor</strong>.</p>
<p>I created two agents that manage the jobs.&nbsp;&nbsp;One of the agents is&nbsp;called <strong>runAgent</strong> and it&nbsp;starts the jobs by calling <strong>Async.StartWithContinuations</strong>.&nbsp;&nbsp;In the call to <strong>StartWithContinuations</strong>, <span style="background-color: #ccffcc;">which is highlighted in green in the code</span>,&nbsp;I specify the code I want to run when the job completes.&nbsp; In this case, the code posts a message&nbsp;to another agent called&nbsp;<strong>completeAgent</strong>, as well as the code I want to run when the job is canceled. The second argument is the exception continuation, which is not used.&nbsp;</p>
<p><span style="color: green;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; // This agent processes when jobs are completed.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> completeAgent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (id, result) = inbox.Receive()</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printAgent.Post &lt;| sprintf <span style="color: maroon;">"The result of job #%d is %f"</span> id result</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Remove from the list of jobs.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[id] &lt;- { jobs.[id] <span style="color: blue;">with</span> state = JobState.Completed}</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// This agent starts each job in the order it is received.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> runAgent = MailboxProcessor&lt;Job&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; </span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> job = inbox.Receive()</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> str = sprintf <span style="color: maroon;">"Starting job #%d"</span> job.id</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">match</span> jobs.ParentId(job.id) <span style="color: blue;">with</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Some id <span style="color: blue;">-&gt;</span> printAgent.Post &lt;| sprintf <span style="color: maroon;">"%s with parentId #%d"</span> str id</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | None <span style="color: blue;">-&gt;</span> printAgent.Post str</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Add the new job information to the list of running jobs.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[job.id] &lt;- { jobs.[job.id] <span style="color: blue;">with</span> state = JobState.Running }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Start the job.</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="background-color: #ccffcc;">Async.StartWithContinuations(job.comp,</span></span></p>
<p style="margin: 0px;"><span style="background-color: #ccffcc;"><span style="font-family: courier new,courier;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> result <span style="color: blue;">-&gt;</span> completeAgent.Post(job.id, result)),</span></span></span></p>
<p style="margin: 0px;"><span style="background-color: #ccffcc;"><span style="font-family: courier new,courier;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()),</span></span></span></p>
<p style="margin: 0px;"><span style="background-color: #ccffcc;"><span style="font-family: courier new,courier;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> cancelException <span style="color: blue;">-&gt;</span> printAgent.Post &lt;| sprintf <span style="color: maroon;">"Canceled job #%d"</span> job.id),</span></span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; job.token</span><span style="background-color: #ccffcc;">)</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</span></p>
<p>I decided to create an agent for printing to the console, also, to make sure that a full string is printed completely before another string is printed, instead of having the output interleaved.</p>
<p><span style="font-family: courier new,courier;"><span style="color: blue;">let</span> printAgent = MailboxProcessor&lt;string&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> str = inbox.Receive()</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"%s"</span> str</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;"></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;"></span></p>
<p style="margin: 0px;"><span style="font-family: arial,helvetica,sans-serif;"></span></p>
<p style="margin: 0px;"><span style="font-family: arial,helvetica,sans-serif;">This&nbsp;means I can use&nbsp;the following syntax to print. Notice the use of the reverse pipe (&lt;|) which means I don't have to use parentheses:</span></p>
<p style="margin: 0px;"><span style="font-family: arial,helvetica,sans-serif;"></span></p>
<p style="margin: 0px;"><span style="font-family: arial,helvetica,sans-serif;"></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;"></span></p>
<p style="margin: 0px;"><span style="font-family: courier new,courier;">printAgent.Post &lt;| sprintf <span style="color: maroon;">"The result of job #%d is %f"</span> id result</span></p>
<p>Here is the complete code:</p>
<div style="background: white; color: black; font-size: 10pt;"><span style="font-family: arial,helvetica,sans-serif;">&nbsp;&nbsp;</span><span style="font-family: arial,helvetica,sans-serif;">&nbsp;</span></div>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> JobAgentsWithCancellation =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System.Threading</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> random = System.Random()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// The state of the job.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> JobState =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | NotStarted</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Running</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Canceled</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Completed</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Result = double</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// a Job consists of a job ID, a computation, a cancellation token source,</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// and a state.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Job = {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; id : int</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; comp : Async&lt;Result&gt;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; token : CancellationToken</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; state : JobState</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = int * Result</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// Generates mock jobs using Async.Sleep</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> createJob(id:int, token:CancellationToken) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> job = async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Let the time be a random number between 1 and 10000</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// And the mock computed result is a floating point value</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> time = random.Next(10000)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> result = 2.0 + random.NextDouble()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> count = ref 0</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Start child jobs</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (!count &lt;= 100) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> Async.Sleep(time / 100)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; count := !count + 1</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; { id = id; comp = job; token = token; state = JobState.NotStarted }</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// The&nbsp;ID of the job whose status changed and the new status.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> JobStatusChangedMessage = int * JobState</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> JobCollection(numJobs) =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> tokenSources = Array.init numJobs (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> <span style="color: blue;">new</span> CancellationTokenSource())</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// The problem is that&nbsp;an array is mutable shared data, so all updates will be</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// managed by a jobsStatus agent.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> jobs = Array.init numJobs (<span style="color: blue;">fun</span> id <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; createJob(id, tokenSources.[id].Token))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> parentIds = Array.create numJobs None</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> jobsStatusAgent = MailboxProcessor&lt;JobStatusChangedMessage&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> jobId, jobState = inbox.Receive()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[jobId] &lt;- { jobs.[jobId] <span style="color: blue;">with</span> state = jobState }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.Item</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">with</span> get(index) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[index]</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">and</span> set index (value : Job) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobsStatusAgent.Post(index, value.state)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.TokenSource <span style="color: blue;">with</span> get(index) = tokenSources.[index]</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.ParentId <span style="color: blue;">with</span> get(index) = parentIds.[index]</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.Length = jobs.Length</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Child jobs have the same CancellationToken as the parent job, so</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// if you cancel the parent job, the child jobs are also cancelled.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// This function locks the collection during these modifications.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">member</span> this.AddChildJobs(numJobs, parentId) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; lock this (<span style="color: blue;">fun</span> () <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> firstNewId = jobs.Length</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> newJobs = Array.init numJobs (<span style="color: blue;">fun</span> id <span style="color: blue;">-&gt;</span> createJob(firstNewId + id, jobs.[parentId].token))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> newTokenSources = Array.create numJobs tokenSources.[parentId]</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <span style="color: blue;">let</span> newParentIds = Array.create numJobs (Some(parentId))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; jobs &lt;- Array.append jobs newJobs </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; tokenSources &lt;- Array.append tokenSources newTokenSources</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; parentIds &lt;- Array.append parentIds newParentIds)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> numJobs = 10</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> jobs = <span style="color: blue;">new</span> JobCollection(numJobs)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; jobs.AddChildJobs(4, 2)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> printAgent = MailboxProcessor&lt;string&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> str = inbox.Receive()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"%s"</span> str</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// This agent processes when jobs are completed.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> completeAgent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (id, result) = inbox.Receive()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printAgent.Post &lt;| sprintf <span style="color: maroon;">"The result of job #%d is %f"</span> id result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Remove from the list of jobs.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[id] &lt;- { jobs.[id] <span style="color: blue;">with</span> state = JobState.Completed}</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// This agent starts each job in the order it is received.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> runAgent = MailboxProcessor&lt;Job&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> job = inbox.Receive()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> str = sprintf <span style="color: maroon;">"Starting job #%d"</span> job.id</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">match</span> jobs.ParentId(job.id) <span style="color: blue;">with</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | Some id <span style="color: blue;">-&gt;</span> printAgent.Post &lt;| sprintf <span style="color: maroon;">"%s with parentId #%d"</span> str id</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | None <span style="color: blue;">-&gt;</span> printAgent.Post str</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Add the new job information to the list of running jobs.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[job.id] &lt;- { jobs.[job.id] <span style="color: blue;">with</span> state = JobState.Running }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Start the job.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="background-color: #ccffcc;">Async.StartWithContinuations(job.comp,</span></p>
<p style="margin: 0px;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> result <span style="color: blue;">-&gt;</span> completeAgent.Post(job.id, result)),</span></p>
<p style="margin: 0px;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()),</span></p>
<p style="margin: 0px;"><span style="background-color: #ccffcc;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> cancelException <span style="color: blue;">-&gt;</span> printAgent.Post &lt;| sprintf <span style="color: maroon;">"Canceled job #%d"</span> job.id),</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="background-color: #ffff99;">job.token</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">for</span> id <span style="color: blue;">in</span> 0 .. jobs.Length - 1 <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; runAgent.Post(jobs.[id])</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> cancelJob(cancelId) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (cancelId &gt;= 0 &amp;&amp; cancelId &lt; numJobs &amp;&amp; jobs.[cancelId].state = JobState.Running) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.[cancelId] &lt;- { jobs.[cancelId] <span style="color: blue;">with</span> state = JobState.Canceled }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jobs.TokenSource(cancelId).Cancel()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printAgent.Post &lt;| sprintf <span style="color: maroon;">"Cancelling job #%d"</span> cancelId</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printAgent.Post &lt;| sprintf <span style="color: maroon;">"Job #%d could not be canceled."</span> cancelId</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printAgent.Post &lt;| <span style="color: maroon;">"Specify a job by number to cancel it, and then press Enter."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> finished = <span style="color: blue;">false</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> not finished <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = System.Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> a = ref 0</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (Int32.TryParse(input, a) = <span style="color: blue;">true</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cancelJob(!a)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printAgent.Post &lt;| <span style="color: maroon;">"Closing."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; finished &lt;- <span style="color: blue;">true</span></p>
</div>
<p>&nbsp;Here is an example session that shows that job #2 has four children, and that&nbsp;if you cancel job #2, all the child jobs are cancelled also.</p>
<p>Specify a job by number to cancel it, and then press Enter.<br />Starting job #0<br />Starting job #1<br />Starting job #2<br />Starting job #3<br />Starting job #4<br />Starting job #5<br />Starting job #6<br />Starting job #7<br />Starting job #8<br />Starting job #9<br />Starting job #10 with parentId #2<br />Starting job #11 with parentId #2<br />Starting job #12 with parentId #2<br />Starting job #13 with parentId #2<br />2<br />Cancelling job #2<br />Canceled job #13<br />Canceled job #2<br />Canceled job #11<br />Canceled job #10<br />Canceled job #12<br />The result of job #3 is 2.801492<br />The result of job #0 is 2.164704<br />The result of job #7 is 2.930089<br />The result of job #5 is 2.191637<br />The result of job #6 is 2.558175<br />The result of job #1 is 2.398534<br />The result of job #8 is 2.462594<br />The result of job #9 is 2.575942<br />The result of job #4 is 2.051622</p>
<p>In the next post, we'll look at utilizing multiple CPU cores by limiting the number of running jobs to be equal to the number of processors available.</p>
<p>Gordon</p>]]></content:encoded>
    </item>
    <item>
      <title>Using F# agents to manage background jobs</title>
      <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/using-f-agents-to-manage-background-jobs</link>
      <pubDate>Wed, 12 Jan 2011 18:23:00 GMT</pubDate>
      <dc:creator><![CDATA[GordonHogenson1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gordonhogenson/2011/01/12/using-f-agents-to-manage-background-jobs/</guid>
      <description><![CDATA[In a previous post, I started out with some simple F# agents.&nbsp; As we saw previously, agents...]]></description>
      <content:encoded><![CDATA[<p>In a<a href="https://blogs.msdn.com/b/gordonhogenson/archive/2011/01/10/f-agents-with-timeouts.aspx" title="previous post"> previous post</a>, I started out with some simple F# agents.&nbsp; As we saw previously, agents process&nbsp;messages in a queue&nbsp;and perform actions in response. In the previous post, I created a simple console application that starts an agent, and then starts a loop that reads each line of input from the console and submits it to the agent.&nbsp; The intention is to build up the code to produce a small console app that I can use to launch and control background jobs.&nbsp; The first change from the previous code is to allow multiple messages to be sent before waiting for a reply on the reply channel.&nbsp;This means that instead of using PostAndReply to send a message to the agent, I need to use PostAndAsyncReply.&nbsp; Just changing the function changes the return value so that now an asynchronous workflow object (in this case Async&lt;Message&gt;) is returned.&nbsp; I need to start this.&nbsp; I have&nbsp;several options.&nbsp; Just to get started, let's just run the workflow by&nbsp;using&nbsp;Async.RunSynchronously.&nbsp; This results in code that is pretty much equivalent to PostAndReply, since the asynchronous workflow is&nbsp;only being used in a synchronous way.&nbsp; The code will still block waiting for the reply to each job before enabling you to start another one.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorTest =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (message = <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(<span style="color: maroon;">"Stop"</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type some text and press Enter to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type 'Stop' to terminate."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop() =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> replyAsync = agent.PostAndAsyncReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Wait for reply.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> reply = Async.RunSynchronously(replyAsync);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (reply &lt;&gt; <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Reply: %s"</span> reply</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press Enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;I can think of two other&nbsp;options.&nbsp;&nbsp;I could start it as a task by using Async.StartAsTask.&nbsp; StartAsTask launches a .NET Framework Task and then returns control immediately, so it is asynchronous.&nbsp; The return value is a Task object, and so I could start a number of tasks and maintain a collection of the&nbsp;tasks that are currently running, and track them when they complete.&nbsp; Here is what the code looks like using tasks:</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorTest =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (message = <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(<span style="color: maroon;">"Stop"</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type some text and press Enter to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type 'Stop' to terminate."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> isCompleted = <span style="color: blue;">false</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> tasks = []</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (not isCompleted) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> replyAsync = agent.PostAndAsyncReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Wait for reply.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> task = Async.StartAsTask(replyAsync);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Add to task collection.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tasks &lt;- task :: tasks</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Check tasks for completion</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// and display the results of completed tasks.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> newTaskList = []</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">for</span> task <span style="color: blue;">in</span> tasks <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (task.IsCompleted) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> result = task.Result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (result &lt;&gt; <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Task result: %s"</span> result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; isCompleted &lt;- <span style="color: blue;">true</span>;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; newTaskList &lt;- task :: newTaskList</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tasks &lt;- newTaskList</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;</p>
<p>I think it actually is simpler to just use Async.StartWithContinuations.&nbsp; Instead of having to manage a Task object, I can just specify the code I want to run when the reply is available.&nbsp; This is referred to as a continuation function, and I can just specify this function as a lambda expression in the arguments to Async.StartWithContinuations.&nbsp; I really like Async.StartWithContinuations.&nbsp; Being able to specify code to run later in a simple lambda expression seems pretty powerful.&nbsp; There are actually three different continuation functions that Async.StartWithContinuations accepts. The first is the code to run when&nbsp;a result is available. The second is the code to run when an exception occurs, and the third is the code to run when an operation is canceled.&nbsp;&nbsp;In this case, we're only using the first one.&nbsp; Next time we'll look at using the cancellation continuation.&nbsp; The exception continuation won't be used in these examples, because the mailbox processor has a different mechanism for&nbsp;transmitting exceptions, using the Error event,&nbsp;which I&nbsp;showed&nbsp;at the end of the <a href="https://blogs.msdn.com/b/gordonhogenson/archive/2011/01/10/f-agents-with-timeouts.aspx" title="previous blog post">previous blog post</a>.&nbsp;</p>
<p>&nbsp;I'll also add some code to delay when the messages return, so it is more obvious that this is working&nbsp;asynchronously, and because I expect the jobs to do that when I write my job agent.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span>&nbsp;MailboxProcessorTest =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Delay so that the responses come in a different order.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> Async.Sleep( 5000 - 1000 * n);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type some text and press Enter to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> isCompleted = <span style="color: blue;">false</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (not isCompleted) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> messageAsync = agent.PostAndAsyncReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Set up a continuation function (the first argument below) that prints the reply.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// The second argument is the exception continuation (not used).</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// The third argument is the cancellation continuation (not used).</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Async.StartWithContinuations(messageAsync, </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> reply <span style="color: blue;">-&gt;</span> printfn <span style="color: maroon;">"%s"</span> reply),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press Enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
</div>
<p>&nbsp;</p>
<p>Here an example session.&nbsp; It looks a bit messy, because the output is interleaved with the input.&nbsp; Output just appears whenever a job completes.</p>
<p><span style="font-family: courier new,courier;">Mailbox Processor Test<br />Type some text and press Enter to submit a message.<br />&gt; test<br />&gt; test2<br />&gt; test3<br />&gt; test4<br />&gt; tMessage number 0 was received. Message contents: test<br />est5<br />&gt; Message number 1 was received. Message contents: test2<br />Message number 2 was received. Message contents: test3<br />Message number 3 was received. Message contents: test4<br />Message number 4 was received. Message contents: test5</span></p>
<p>OK. So now&nbsp;that I have figured out the basic mechanics, I am ready to write my job agent.&nbsp; I'm going to start with a mock job, which is just going to sleep for a random amount of time.&nbsp; I have added a createJob function that takes a job ID and creates a simulated job.&nbsp; I'm going to submit this job instead of the string as the Message, and I'm going to change the reply to include the result of the job and its ID.&nbsp; To actually start the job, I'm going to use StartWithContinuations within the message loop and the reply is going to be sent in the continuation.&nbsp; That way all the jobs start at once, but the replies come in a staggered fashion as the jobs finish.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> JobAgent =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> random = System.Random()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// Generates mock jobs using Async.Sleep.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> createJob(id:int) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> job = async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Let the time be a random number between 1 and 10000,</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// and the mock computed result is a floating point value.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> time = random.Next(10000)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> result = random.NextDouble()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> Async.Sleep(time)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; id, job</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Result = double</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// a Job consists of a job ID, and a computation that produces a single result.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Job = int * Async&lt;Result&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = Job * AsyncReplyChannel&lt;int * Result&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> (jobID, job) = message</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Starting job #%d"</span> jobID</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Set up the reply to be submitted when the job completes.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Async.StartWithContinuations(job,</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (<span style="color: blue;">fun</span> result <span style="color: blue;">-&gt;</span> replyChannel.Reply(jobID, result)),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Starting 10 jobs."</span>&nbsp;&nbsp; </p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop(count) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = createJob(count)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> replyAsync = agent.PostAndAsyncReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Post the job request</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Async.StartWithContinuations(replyAsync, (<span style="color: blue;">fun</span> (id, result) <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Result of job %d is %f."</span> id result),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()), <span style="color: green;">// exception continuation not used</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> count &lt; 10 <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop(count + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop(0)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press Enter to close."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
</div>
<p>&nbsp;</p>
<p>Here is an example of the output of the previous code:</p>
<p><span style="font-family: courier new,courier;">Starting 10 jobs.<br />Press Enter to close.<br />Starting job #0<br />Starting job #1<br />Starting job #2<br />Starting job #3<br />Starting job #4<br />Starting job #5<br />Starting job #6<br />Starting job #7<br />Starting job #8<br />Starting job #9<br />Starting job #10<br />Result of job 5 is 0.784409.<br />Result of job 2 is 0.668888.<br />Result of job 4 is 0.747429.<br />Result of job 3 is 0.961764.<br />Result of job 1 is 0.278119.<br />Result of job 8 is 0.469319.<br />Result of job 10 is 0.495857.<br />Result of job 0 is 0.629329.<br />Result of job 7 is 0.483028.<br />Result of job 9 is 0.451606.<br />Result of job 6 is 0.514781.</span></p>
<p>Now let's actually calculate something interesting.&nbsp; The code changes slightly, since now we're taking a lambda for the function to run to compute a result.&nbsp; Also, the result is going to be a generic quantity.&nbsp; I want the generic type to be inferred, so I'm going to use the wildcard character (_) in one place where I would normally have to put in the exact type.&nbsp; In this case, the result type is going to be BigInteger, since we're computing the Nth prime numbers.&nbsp; There are definitely more efficient ways of computing&nbsp;prime numbers,&nbsp;but the main point here is to demonstrate running a computation, not to optimize that calculation.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> JobAgent =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> random = System.Random()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// Generates mock jobs using Async.Sleep.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> createJob(id:int, computation, input : int) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> job = async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Let the time be a random number between 1 and 10000,</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// and the mock computed result is a floating point value.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> time = random.Next(10000)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> result = computation(input)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">return</span> result</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; id, job</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// a Job consists of a job ID, a computation that produces a single result.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Job&lt;'T&gt; = int * Async&lt;'T&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message&lt;'T&gt; = Job&lt;'T&gt; * AsyncReplyChannel&lt;int * 'T&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&lt;_&gt;&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> (jobID, job) = message</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Starting job #%d"</span> jobID</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Set up the reply to be submitted when the job completes.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Async.StartWithContinuations(job,</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (<span style="color: blue;">fun</span> result <span style="color: blue;">-&gt;</span> replyChannel.Reply(jobID, result)),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Computing the Nth prime numbers."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: green;">// Recursive isprime function.</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> isprime number =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> check count =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; count &gt; number/2 || (number % count &lt;&gt; 0 &amp;&amp; check (count + 1))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; check 2</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> isprimeBigInt number =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> check count =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; count &gt; number/2I || (number % count &lt;&gt; 0I &amp;&amp; check (count + 1I))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; check 2I</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> computeNthPrime (number) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (number &lt; 1) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; invalidOp &lt;| sprintf <span style="color: maroon;">"Invalid input for nth prime: %s."</span> (number.ToString())</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> count = 0</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> num = 1I</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> isDone = <span style="color: blue;">false</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (count &lt; number) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; num &lt;- num + 1I</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (num &lt; bigint System.Int32.MaxValue) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (not (isprime (int num))) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; num &lt;- num + 1I</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (not (isprimeBigInt num)) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; num &lt;- num + 1I</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; count &lt;- count + 1</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; num&nbsp; </p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> multiplier = 1000</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop(id) =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = createJob(id, (<span style="color: blue;">fun</span> n <span style="color: blue;">-&gt;</span> computeNthPrime(n) ), multiplier * id )</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> replyAsync = agent.PostAndAsyncReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Post the job request</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Async.StartWithContinuations(replyAsync, (<span style="color: blue;">fun</span> (id, result) <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Nth Prime for N = %d is %s."</span> (multiplier*id) (result.ToString())),</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()), <span style="color: green;">// exception continuation not used</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; (<span style="color: blue;">fun</span> _ <span style="color: blue;">-&gt;</span> ()))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> id &lt; 10 <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop(id + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop(1)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press Enter to close."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;Here is some output.&nbsp; On my computer, which is running an Intel Core Duo processor, about&nbsp;two jobs seem to be able to run at the same time.</p>
<p><span style="font-family: courier new,courier;">Computing the Nth prime numbers.<br />Press Enter to close.<br />Starting job #1<br />Starting job #2<br />Nth Prime for N = 1000 is 7919.<br />StartinNth Prime for N = 2000 is 17389.<br />g job #3<br />Starting job #4<br />Nth Prime for N = 3000 is 27449.<br />Starting job #5<br />Nth Prime for N = 4000 is 37813.<br />Starting job #6<br />Nth Prime for N = 5000 is 48611.<br />StartNth Prime for N = in6000 is 59359.<br />g job #7<br />Starting job #8<br />Nth Prime for N = 7000 is 70657.<br />Starting job #9<br />Nth Prime for N = 8000 is 81799.<br />Starting job #Nth Prime for N = 9000 is 93179.<br />10<br />Nth Prime for N = 10000 is 104729.</span></p>
<p>That's all for now.&nbsp; Next time, instead of using the reply channel to communicate back to the thread that posts the messages, I'll use multiple agents (one for job requests, one for running jobs, and one for completion notifications)&nbsp;and we'll look at how to get the currently running jobs and how to cancel jobs.&nbsp; I was impatient, so I set the multiplier for N to be only 1000.&nbsp; You could try copying this code and changing that number to a larger one.</p>
<p>Gordon</p>]]></content:encoded>
    </item>
    <item>
      <title>F# agents with timeouts</title>
      <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/f-agents-with-timeouts</link>
      <pubDate>Mon, 10 Jan 2011 16:52:00 GMT</pubDate>
      <dc:creator><![CDATA[GordonHogenson1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gordonhogenson/2011/01/10/f-agents-with-timeouts/</guid>
      <description><![CDATA[In my previous post, I showed a code snippet with a very simple F# agent console application.&nbsp;...]]></description>
      <content:encoded><![CDATA[<p>In my <a href="https://blogs.msdn.com/b/gordonhogenson/archive/2011/01/06/welcome-to-gordon-hogenson-s-f-blog.aspx" title="previous post">previous post</a>, I showed a code snippet with a very simple F# agent console application.&nbsp; You run the app from the console, and every time you enter a line of text, it generates a new message and posts it to the message queue of an F# agent.&nbsp; An agent is an instance of the <a href="https://msdn.microsoft.com/en-us/library/ee370357.aspx" title="MailboxProcessor">MailboxProcessor</a> class.&nbsp; The MailboxProcessor is a class in the F# core library in the Control namespace.&nbsp; As the name MailboxProcessor implies, an agent is something that you can send messages to, and it runs some code in response to messages that you send.&nbsp; The code that it runs is conveniently expressed as a lambda expression that you pass in.</p>
<p>Typically the lambda expressions that you pass in will all follow a common pattern, which is a loop that repeatedly takes a message from the queue, one at a time.&nbsp; You call the&nbsp;Receive method on each iteration of the loop.</p>
<p>Here is the sample code that I posted the other day.&nbsp; In this code, we create one agent and its message-processing loop as I've just described.&nbsp; Additionally, we run a loop that reads one line at a time from the console and sends each line to the agent.&nbsp; If you run this program, then every time you enter some text, the text is received as a message.&nbsp;&nbsp;In addition to the basic message processing, this example shows how to&nbsp;send&nbsp;information back to the caller by using the reply channel, an object of type AsyncReplyChannel.&nbsp; The only processing that happens in this simple example is that if the message is "Stop" then send a special reply, otherwise send a reply that we've received a message, along with the ID and text of the message.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorTest2 =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (message = <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(<span style="color: maroon;">"Stopping."</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span>&nbsp;&nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop 0)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Enter some text and hit ENTER to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type 'Stop' to terminate."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop() =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> reply = agent.PostAndReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (reply &lt;&gt; <span style="color: maroon;">"Stopping."</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Reply: %s"</span> reply</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
</div>
<p>&nbsp;</p>
<p>The other interesting thing is the async { ... } in the message processing loop.&nbsp; Asynchronous programming is one of the strengths of F#.&nbsp; MailboxProcessor is designed to work asynchronously. So, for example, the return type of the lambda expression is Async&lt;unit&gt;,&nbsp;an asynchronous work item.&nbsp; This allows us to start to listen to messages but not block on waiting for the next message.&nbsp; The use of let! instead of let, and do! instead of do indicates an asynchronous operation.&nbsp; The basic idea is that execution goes up until a let! or do! and then, if no return or completion is ready, execution can go on elsewhere. Then, when a return value is available, or the execution is complete, then the program continues from that point.&nbsp; Behind the scenes, a callback is used and the remaining code after the let! or do! is packaged up into the callback.&nbsp; Obviously all of that is rather complicated, so&nbsp;what people like&nbsp;about the design is that&nbsp;you can write asynchronous code much as&nbsp;you would write synchronous code, with a few extra bangs (!) here and there, and F# asynchronous workflows&nbsp;take care of making it asynchronous.</p>
<p>The asynchronous feature of F# is one of its most attractive features.&nbsp; In fact, it was so nicely done that it is being implemented in C# and Visual Basic as well, and you can try that out in a <a href="https://msdn.microsoft.com/en-us/vstudio/async.aspx" title="CTP Release">CTP release</a> that came out in the fall of 2010 at the PDC conference.&nbsp; It can seem a bit like a black box though.&nbsp; One thing I hope to do in this series of blog posts is to explore the asynchronous programming model and hopefully elucidate this black box.&nbsp; In particular, we want to have a mental model of how to think about how it operates.&nbsp; It would be one thing if all it did was fire up a background thread every time a new logical "program flow" came into play.&nbsp; In this example, we have two loops going, one that reads input, and one that processes messages.&nbsp; You would think that there are two threads going on in parallel since there are these two loops happening "at the same time".&nbsp; Let's test this theory by printing out the Thread ID.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> printThreadId note =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Append the Thread ID</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"%d : %s"</span> System.Threading.Thread.CurrentThread.ManagedThreadId note</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;Then add some code that calls this printThreadId method, with either an argument of "MailboxProcessor" or "Console".&nbsp; If you run this, you'll find that indeed it is true, the MailboxProcessor loop is running on separate threads from the UI thread that is reading from the console.&nbsp; I found when running this that there were in fact two background threads reading messages from the queue.&nbsp; Here is the code after adding these changes:</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorTest2 =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> printThreadId note =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: green;">// Append the Thread ID</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"%d : %s"</span> System.Threading.Thread.CurrentThread.ManagedThreadId note</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printThreadId <span style="color: maroon;">"mailboxProcessor"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (message = <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(<span style="color: maroon;">"Stopping."</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop 0)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Enter some text and hit ENTER to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type 'Stop' to terminate."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop() =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printThreadId(<span style="color: maroon;">"Console loop"</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> reply = agent.PostAndReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (reply &lt;&gt; <span style="color: maroon;">"Stopping."</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Reply: %s"</span> reply</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
</div>
<p>&nbsp;</p>
<p>And here is some of my output:</p>
<p>Mailbox Processor Test<br />Enter some text and hit ENTER to submit a message.<br />Type 'Stop' to terminate.<br />&gt; test<br />1 : Console loop<br />4 : mailboxProcessor<br />Reply: Message number 0 was received. Message contents: test<br />&gt; another loop<br />1 : Console loop<br />3 : mailboxProcessor<br />Reply: Message number 1 was received. Message contents: another loop<br />&gt; another loop<br />1 : Console loop<br />4 : mailboxProcessor<br />Reply: Message number 2 was received. Message contents: another loop<br />&gt; testing<br />1 : Console loop<br />3 : mailboxProcessor<br />Reply: Message number 3 was received. Message contents: testing<br />&gt; testing<br />1 : Console loop<br />4 : mailboxProcessor<br />Reply: Message number 4 was received. Message contents: testing</p>
<p>Let's suppose we want to now add some timeout condition, so that after a while of no new input from the console, the app&nbsp;posts a note saying that a timeout occurred and skips to the next message ID.&nbsp; Receive takes a timeout as an optional argument, which is an integer in milleseconds.&nbsp;&nbsp;I set a timeout of 10 seconds.&nbsp; If the timeout is exceeded, TimeoutException is thrown.&nbsp;&nbsp; I want to catch this exception, but at first, I tried to put the try/with&nbsp;outside the call to PostAndReply.&nbsp;&nbsp;But,&nbsp;the exception was never caught!&nbsp;&nbsp;&nbsp;&nbsp;I can only catch the exception on the same thread where it is generated, so the exception handler has to be in the mailbox processor message loop.&nbsp;&nbsp;I also had to be careful to&nbsp;start the next loop iteration in the case of a timeout.&nbsp; Ouch, I got a bit caught by the fact that F# asynchronous workflows are so smooth, I&nbsp;don't even know&nbsp;I'm running on a separate thread.&nbsp;&nbsp; Here is an implementation of the timeout&nbsp;that works.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorTest3 =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">try</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive(10000);</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (message = <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(<span style="color: maroon;">"Stop"</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">with</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | :? TimeoutException <span style="color: blue;">-&gt;</span> </p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"The mailbox processor timed out."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop (0))</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Enter some text and hit ENTER to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type 'Stop' to terminate."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop() =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> reply = agent.PostAndReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (reply &lt;&gt; <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Reply: %s"</span> reply</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;</p>
<p>Now, when you run this, if you wait long enough, the timeout message will be printed, but the processing of new messages continues, and&nbsp;the message&nbsp;id number&nbsp;will skip one.&nbsp; Here is an example session:</p>
<p>Mailbox Processor Test<br />Enter some text and hit ENTER to submit a message.<br />Type 'Stop' to terminate.<br />&gt; hello<br />Reply: Message number 0 was received. Message contents: hello<br />&gt; hello?<br />Reply: Message number 1 was received. Message contents: hello?<br />&gt; The mailbox processor timed out.<br />testing<br />Reply: Message number 3 was received. Message contents: testing<br />&gt; Stop<br />Press enter to continue.</p>
<p>However there are definitely times when you want the exception to be propagated to the thread that posted the message.&nbsp; It is possible to do this, with the Error event.&nbsp; The Error event takes a lambda expression that processes an exception.&nbsp; Here is an example where the agent throws a timeout exception and it is handled by the Error event.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorWithError =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> message = inbox.Receive(10000);</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Message number %d. Message contents: %s"</span> n message</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n+1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop 0)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; agent.Error.Add(<span style="color: blue;">fun</span> exn <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">match</span> exn <span style="color: blue;">with</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | :? System.TimeoutException <span style="color: blue;">as</span> exn <span style="color: blue;">-&gt;</span> printfn <span style="color: maroon;">"The agent timed out."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; printfn <span style="color: maroon;">"Press Enter to close the program."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; exit(1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; | _ <span style="color: blue;">-&gt;</span> printfn <span style="color: maroon;">"Unknown exception."</span>)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type some text and press Enter to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> <span style="color: blue;">true</span> <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; agent.Post</p>
<p style="margin: 0px;">&nbsp;</p>
</div>
<p>&nbsp;</p>
<p>Where I'm headed with this, is I want to create a job agent that will allow me to start some background jobs from a command prompt.&nbsp; The timeout isn't really necessary, but it did help clarify the behavior of exceptions that take place in the message loop.&nbsp; If I want to start jobs in the background, I'm going to want to start up multiple jobs at a time, so it won't do to submit one message and then have to wait until PostAndReply returns!&nbsp; I will need to use PostAndAsyncReply, so in the next version, both the message processing loop and the input loop will be asynchronous.</p>
<p>Gordon</p>]]></content:encoded>
    </item>
    <item>
      <title>Welcome to Gordon Hogenson's F# Blog</title>
      <link>https://docs.microsoft.com/archive/blogs/gordonhogenson/welcome-to-gordon-hogensons-f-blog</link>
      <pubDate>Thu, 06 Jan 2011 13:09:00 GMT</pubDate>
      <dc:creator><![CDATA[GordonHogenson1]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/gordonhogenson/2011/01/06/welcome-to-gordon-hogensons-f-blog/</guid>
      <description><![CDATA[I'm the technical writer who wrote most of&nbsp;the MSDN documentation for F#, and I decided to...]]></description>
      <content:encoded><![CDATA[<p>I'm the technical writer who wrote most of&nbsp;the MSDN documentation for F#, and I decided to start&nbsp;a less formal channel of communication to share some of what I'm learning about F# and associated technologies.</p>
<p>But first a few notes about how to let me know about problems and other feedback for the F# MSDN docs.&nbsp; First to clarify what I actually am responsible for.&nbsp; Anything with an address that includes msdn.microsoft.com/library and is related to F#, I am interested in hearing feedback on.&nbsp; In terms of the specific table of contents areas in the MSDN TOC, that is anything under this node: <a href="https://msdn.microsoft.com/en-us/library/dd233154.aspx">https://msdn.microsoft.com/en-us/library/dd233154.aspx</a>.&nbsp; The feedback link is harder to find in MSDN's lightweight view, but it is there at the very bottom of the page.&nbsp; Any comments you put into the feedback box will make it to me, unless it gets caught up in the spam filter, which it shouldn't unless you are using the feedback link to advance your Viagra business.</p>
<p>One of the things that this blog will include is lots of F# programs!&nbsp; In the course of my responsibilities, I often write small pieces of code, and sometimes larger projects.&nbsp; Much of this is an effort to explore the ins and out of some particular aspect of the F# language and the F# core library.&nbsp; For example, over the past year, I've written some examples using F#'s asynchronous workflows, the F# MailboxProcessor, and the like.</p>
<p>The other thing that I'm interested in is the transition from&nbsp;other languages, like C++ and C#,&nbsp;to F#.&nbsp; As a C++ and C# programmer, I am familiar with a certain paradigm of computing, but I also was vaguely familiar with the idea of functional programming.&nbsp; Over the last several years, I've had the opportunity to explore the functional programming paradigm, and I'm interested in how this changes the way we think about solving everyday programming problems and how this way of thinking might improve how I design new APIs.&nbsp; For example, how do I code without using mutable variables?&nbsp; And maybe more importantly, when&nbsp;is it beneficial to&nbsp;code without mutable variables, and when is it being too pedantic?</p>
<p>And then there are the larger software engineering questions, such as, can adopting a functional approach improve the ability of a team to deliver&nbsp;great products?&nbsp; The promise of functional programming of greatest interest to those who run software businesses is that it makes it easier to write code that is&nbsp;stable and is easier to maintain.&nbsp; One of the larger things that we at Microsoft are learning in embracing a functional language like F# is how using this type of programming can benefit our industry.</p>
<p>To get us warmed up, I'll say that I've been looking at the MailboxProcessor lately.&nbsp; The F# MailboxProcessor provides a message-passing mechanism that allows you to structure a program as a set of agents which read and respond to a queue of messages.&nbsp; In some ways it is akin to MSMQ, but its inspiration comes from the language Erlang, which is&nbsp;specifically designed to be an&nbsp;agent-based language.&nbsp; F# is not specifically designed for agent-based programming, but the MailboxProcessor provides support for this type of programming.</p>
<p>For example here is a program I wrote recently that starts up a MailboxProcessor. The code defines an agent that runs a loop that reads messages.&nbsp; Here, the message is just a string read from the console window, paired with a reply channel.&nbsp;&nbsp;The agent reads each message and then submits a reply through a reply channel that is passed in.&nbsp; The reply is then printed, or if the special "Stop" command is given by the user, the loop ends.</p>
<h2><span style="font-size: small;">MailboxProcessorTest1.fs</span></h2>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">module</span> MailboxProcessorTest1 =</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">open</span> System</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">type</span> Message = string * AsyncReplyChannel&lt;string&gt;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> formatString = <span style="color: maroon;">"Message number {0} was received. Message contents: {1}"</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> agent = MailboxProcessor&lt;Message&gt;.Start(<span style="color: blue;">fun</span> inbox <span style="color: blue;">-&gt;</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">rec</span> loop n =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; async {</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let!</span> (message, replyChannel) = inbox.Receive();</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (message = <span style="color: maroon;">"Stop"</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(<span style="color: maroon;">"Stopping."</span>)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; replyChannel.Reply(String.Format(formatString, n, message))</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">do!</span> loop (n + 1)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop 0)</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Mailbox Processor Test"</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Enter some text and hit ENTER to submit a message."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Type 'Stop' to terminate."</span></p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> <span style="color: blue;">mutable</span> stop = <span style="color: blue;">false</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span style="color: blue;">while</span> (not stop) <span style="color: blue;">do</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> reply = agent.PostAndReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (reply = <span style="color: maroon;">"Stopping."</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stop &lt;- <span style="color: blue;">true</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Reply: %s"</span> reply</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Press enter to continue."</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; Console.ReadLine() |&gt; ignore</p>
</div>
<p>&nbsp;</p>
<p>&nbsp;One thing I try to do in the documentation is demonstrate how to use functional programming style.&nbsp; Functional programming purists might prefer to rewrite the loop as a recursive function, and eliminate the mutable control variable.</p>
<div style="font-family: Consolas; font-size: 10pt; color: black; background: white;">
<p style="margin: 0px;"><span style="color: blue;">&nbsp;&nbsp;&nbsp; let</span> <span style="color: blue;">rec</span> loop() =</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printf <span style="color: maroon;">"&gt; "</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> input = Console.ReadLine()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">let</span> reply = agent.PostAndReply(<span style="color: blue;">fun</span> replyChannel <span style="color: blue;">-&gt;</span> input, replyChannel)</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">if</span> (reply &lt;&gt; <span style="color: maroon;">"Stopping."</span>) <span style="color: blue;">then</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; printfn <span style="color: maroon;">"Reply: %s"</span> reply</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; loop()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">else</span></p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ()</p>
<p style="margin: 0px;">&nbsp;&nbsp;&nbsp; loop()</p>
</div>
<p>But as a practical person, I now worry, will my recursive function create a stack frame for every iteration, or is F# going to be smart and just reuse the same stack frame for it?&nbsp; If I was confident enough in my knowledge of tail recursion and the F# compiler's tail recursion features, I could deduce all this&nbsp;from the code, but then to be sure I might want to check empirically, so I fired up the debugger and set a breakpoint in the loop, then went through a few iterations on input.&nbsp; In fact, the call stack window shows that there is only one stack frame that is shared for each recursive call.&nbsp; Great, now I know this "functional" form of my code won't blow up the stack.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/42/83/2210.screenshot1.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/1000x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-42-83/2210.screenshot1.jpg" border="0" /></p>
<p>&nbsp;</p>
<p>That's it for today, but clearly the code could be improved.&nbsp; What about adding a timeout and handling what happens then?&nbsp; In the next installment, I will look at how to do this.</p>
<p>Gordon</p>]]></content:encoded>
    </item>
  </channel>
</rss>