<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-39413407965920307</id><updated>2024-10-18T16:34:59.012+11:00</updated><category term="Programming"/><category term="CCR"/><category term="Buffoonery"/><title type='text'>I&#39;m sorry Dave, I&#39;m afraid I can&#39;t do that.</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-6665010175890130708</id><published>2010-03-22T23:44:00.001+11:00</published><updated>2010-03-22T23:44:08.718+11:00</updated><title type='text'>Nomadic</title><content type='html'>&lt;p&gt;I have finally bitten the bullet and got my own &lt;a href=&quot;http://www.monadnomad.com/blog/&quot;&gt;site&lt;/a&gt;. All my old posts have been copied there. Hope to see you there!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/6665010175890130708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/6665010175890130708' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/6665010175890130708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/6665010175890130708'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2010/03/nomadic.html' title='Nomadic'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-2820347767052150979</id><published>2008-12-23T00:35:00.002+11:00</published><updated>2008-12-23T00:41:21.950+11:00</updated><title type='text'>Moving on</title><content type='html'>I&#39;m moving this blog to &lt;a href=&quot;http://iodyner.spaces.live.com/default.aspx&quot;&gt;live spaces&lt;/a&gt;. The feed can be found &lt;a href=&quot;http://iodyner.spaces.live.com/feed.rss&quot;&gt;here&lt;/a&gt;. Despite the rather idiotic restriction of only one category-per-post, I&#39;ve found it marginally easier to format in-line code there, and the ability to put code samples up on a publicly available folder was the clincher.&lt;br /&gt;&lt;br /&gt;Proof perhaps that beggars can be choosers....</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/2820347767052150979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/2820347767052150979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2820347767052150979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2820347767052150979'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2008/12/moving-on.html' title='Moving on'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-8220626335646161428</id><published>2008-10-21T23:57:00.001+11:00</published><updated>2008-10-22T00:11:14.976+11:00</updated><title type='text'>F# Asynchronous Workflows with the Coordination and Concurrency Runtime</title><content type='html'>&lt;p&gt;F# ships with library support for ‘&lt;a href=&quot;http://strangelights.com/blog/archive/2007/10/24/1601.aspx&quot;&gt;mailboxes&lt;/a&gt;’, an asynchronous message-passing mechanism recently popularised by interest in Erlang. This is good news. Message-passing in concurrent systems is always a saner approach than explicitly spawning threads and taking locks, and F#’s support for immutable types and values provides additional safety. Combined with the &lt;a href=&quot;http://blogs.msdn.com/dsyme/archive/2007/10/11/introducing-f-asynchronous-workflows.aspx&quot;&gt;asynchronous workflows&lt;/a&gt; that the language also supports, a powerful Actor-oriented programming model is available to F# developers.&lt;/p&gt;  &lt;p&gt;If you’re playing in this space in .Net though, I still think you can’t go past the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb648752.aspx&quot;&gt;Concurrency and Coordination Runtime&lt;/a&gt; (CCR), especially on performance terms, and it turns out to be straightforward to integrate the CCR with F# asynchronous workflows. &lt;/p&gt;  &lt;p&gt;Let’s start out by defining some basic CCR support – this is mostly just plumbing…&lt;/p&gt;  &lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;#light&lt;br /&gt;&lt;br /&gt;namespace&lt;/span&gt; FSharp.Ccr.Adaptors&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System.Threading&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Ccr.Core&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Ccr.Core.Arbiters&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;type&lt;/span&gt; Receive() = &lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; taskQueue = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; DispatcherQueue()&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;internal&lt;/span&gt; TaskQueue &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;with&lt;/span&gt; get() = taskQueue&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;internal&lt;/span&gt; activate(task : ITask) = &lt;br /&gt;        Arbiter.Activate(taskQueue, [| task |])&lt;/pre&gt;&lt;br /&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In the declaration above, there is only one task queue over the standard CLR thread-pool. I’ll cover the support for specifiable task queues in a later post. Now let’s cover some adaptor code that enables the use of the basic arbiters from within F# asynchronous workflows... &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot;&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;(* &lt;u&gt;&lt;strong&gt;Receive&lt;/strong&gt;.&lt;/u&gt; This allows us to write an asynchronous workflow that waits (but does not block) &lt;br /&gt;       on the port as follows: &lt;br /&gt;    let recv (port : Port&amp;lt;string&amp;gt;) =&lt;br /&gt;        async {&lt;br /&gt;            let! item = Receive.from port&lt;br /&gt;            printfn &amp;quot;%s&amp;quot; item&lt;br /&gt;        }&lt;br /&gt;     *)&lt;/span&gt;    &lt;br /&gt;    [&amp;lt;OverloadID(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&amp;quot;from&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; from (p : Port&amp;lt;&#39;a&amp;gt;) = &lt;br /&gt;        Async.Primitive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; (cont, econt) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            Arbiter.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, p, (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; result &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont result))&lt;br /&gt;            |&amp;gt; Receive.activate)&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;(* &lt;strong&gt;&lt;u&gt;JoinedReceive.&lt;/u&gt;&lt;/strong&gt; This allows us to write an asynchronous workflow that waits (but does not block) &lt;br /&gt;       until both ports have an item for processing. It then returns both in a tuple: &lt;br /&gt;    let recv (p1 : Port&amp;lt;string&amp;gt;, p2 : Port&amp;lt;int&amp;gt;) =&lt;br /&gt;        async {&lt;br /&gt;            let! s1,i1 = Receive.from_both (p1,p2)&lt;br /&gt;            printfn &amp;quot;%s %i&amp;quot; s1 i1&lt;br /&gt;        }&lt;br /&gt;     *)&lt;br /&gt;&lt;/span&gt;    [&amp;lt;OverloadID(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&amp;quot;from_both&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; from_both (p1 : Port&amp;lt;&#39;a&amp;gt;, p2 : Port&amp;lt;&#39;b&amp;gt;) =&lt;br /&gt;        Async.Primitive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; (cont, econt) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            Arbiter.JoinedReceive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, p1, p2, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; a b &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont (a,b))&lt;br /&gt;            |&amp;gt; Receive.activate)&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;(* &lt;strong&gt;&lt;u&gt;Choice.&lt;/u&gt;&lt;/strong&gt; This allows us to write an asynchronous workflow that waits (but does not block) &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; until either port has an item for processing. It then returns the result in a&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Choice:&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; let recv (p : PortSet&amp;lt;string,int&amp;gt;) =&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; async {&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; let! result = Receive.from_either p&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; match result with &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | Choice2_1 s -&amp;gt; printfn &amp;quot;%s&amp;quot; s&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; | Choice2_2 i -&amp;gt; printfn &amp;quot;%i&amp;quot; i&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; *)&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; [&amp;lt;OverloadID(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&amp;quot;from_either&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; from_either (ps : PortSet&amp;lt;&#39;a,&#39;b&amp;gt;) =&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Async.Primitive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; (cont, econt) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Arbiter.Choice(ps, (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; s &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont (Choice2_1 s)), (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; e &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont (Choice2_2 e)))&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; |&amp;gt; Receive.activate) &lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;(* &lt;strong&gt;&lt;u&gt;MultipleItemReceive.&lt;/u&gt;&lt;/strong&gt; This allows us to write an asynchronous workflow that waits (but does not block) &lt;br /&gt;       until n items have queued to the port. It then returns the result in an array.&lt;br /&gt;    let recv (p : Port&amp;lt;string&amp;gt;) =&lt;br /&gt;        async {&lt;br /&gt;            let! result = Receive.multiple_from (p,100)&lt;br /&gt;            printfn &amp;quot;%i items received.&amp;quot; result.Length&lt;br /&gt;        }&lt;br /&gt;     *)&lt;/span&gt; &lt;br /&gt;    [&amp;lt;OverloadID(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&amp;quot;multiple_from&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; multiple_from (p : Port&amp;lt;&#39;a&amp;gt;, n : int) =&lt;br /&gt;        Async.Primitive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; (cont, econt) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            Arbiter.MultipleItemReceive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, p, n, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; r &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont r)      &lt;br /&gt;            |&amp;gt; Receive.activate) &lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;(* &lt;strong&gt;&lt;u&gt;MultipleItemReceive.&lt;/u&gt; &lt;/strong&gt;This allows us to write an asynchronous workflow that waits (but does not block) &lt;br /&gt;       until n items have queued to the portset. It then returns the result as a tuple of&lt;br /&gt;       collections.&lt;br /&gt;    let recv (p : PortSet&amp;lt;string,Exception&amp;gt;) =&lt;br /&gt;        async {&lt;br /&gt;            let! results,failures = Receive.multiple_from_both (p,100)&lt;br /&gt;            printfn &amp;quot;%i results received and %i failures.&amp;quot; results.Count failures.Count&lt;br /&gt;        }&lt;br /&gt;     *)&lt;/span&gt; &lt;br /&gt;    [&amp;lt;OverloadID(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&amp;quot;multiple_from_both&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; multiple_from_both (p : PortSet&amp;lt;&#39;a,&#39;b&amp;gt;, n : int) =&lt;br /&gt;        Async.Primitive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; (cont, econt) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            Arbiter.MultipleItemReceive(p, n, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; f s &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont (f,s))      &lt;br /&gt;            |&amp;gt; Receive.activate)&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;(* &lt;strong&gt;&lt;u&gt;MultiplePortReceive.&lt;/u&gt;&lt;/strong&gt; This allows us to write an asynchronous workflow that waits (but does not block) &lt;br /&gt;       until each port in the specified array has a pending item. It then returns the &lt;br /&gt;       result as a array.&lt;br /&gt;    let recv (p : Port&amp;lt;string&amp;gt; array) =&lt;br /&gt;        async {&lt;br /&gt;            let! results = Receive.from_multiple p&lt;br /&gt;            printfn &amp;quot;%i results received.&amp;quot; results.Length&lt;br /&gt;        }&lt;br /&gt;     *)&lt;/span&gt; &lt;br /&gt;    [&amp;lt;OverloadID(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&amp;quot;from_multiple&amp;quot;&lt;/span&gt;)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; from_multiple (p : Port&amp;lt;&#39;a&amp;gt; array) =&lt;br /&gt;        Async.Primitive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; (cont, econt) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            Arbiter.MultiplePortReceive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, p, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; r &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; cont r)      &lt;br /&gt;            |&amp;gt; Receive.activate)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The Overloads are defined because each of these members has an alternate version that takes a timeout limit. I’ll cover those in the next post.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/8220626335646161428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/8220626335646161428' title='29 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8220626335646161428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8220626335646161428'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2008/10/f-asynchronous-workflows-with.html' title='F# Asynchronous Workflows with the Coordination and Concurrency Runtime'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>29</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-1798211084169858799</id><published>2007-12-02T23:54:00.001+11:00</published><updated>2007-12-02T23:54:23.213+11:00</updated><title type='text'>Bits and Pieces</title><content type='html'>&lt;p&gt;This has been a pretty content-free zone lately. Most of that has been due to work pressure. I&#39;ve got a few systems going live around now and, as always, the last 20% of each project takes 80% of the time. Anyway, I have been looking at a few things here and there that might be of interest...&lt;/p&gt; &lt;p&gt;First off, I noticed that George Chrysanthakopoulos has &lt;a href=&quot;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2491114&amp;amp;SiteID=1&quot;&gt;announced&lt;/a&gt; on the &lt;a href=&quot;http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=1424&amp;amp;SiteID=1&quot;&gt;MSRS CCR forum&lt;/a&gt; that work is underway to unify the CCR with the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/concurrency/default.aspx&quot;&gt;PFX libraries&lt;/a&gt; recently released to CTP, although no time-frames have been given. Additionally, George also states that they are working towards the integration of the CCR into the core .NET libraries (possibly via PFX?). This is excellent news all round. I read with interest the &lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/07/10/Futures/default.aspx&quot;&gt;MSDN article&lt;/a&gt; on the Task Parallel library, which sits at the core of PFX. Actually, in my line of work, I believe the CCR would be more useful than PFX, as taming the asynchrony, whilst exploiting the latent concurrency tends to be the bigger (and harder) problem than parallelising the processing of the data itself. Nevertheless, it&#39;s as a good a vehicle as any in which to ship the CCR and means that in future, if you&#39;re considering the library and don&#39;t work in robotics you won&#39;t have to try and convince your boss why buying and deploying MSRS is a good idea.&lt;/p&gt; &lt;p&gt;I&#39;ve also been following the herd and researching &lt;a href=&quot;http://research.microsoft.com/fsharp/fsharp.aspx&quot;&gt;F#&lt;/a&gt;, following the &lt;a href=&quot;http://blogs.msdn.com/somasegar/archive/2007/10/17/f-a-functional-programming-language.aspx&quot;&gt;announcement&lt;/a&gt; that Microsoft are to fold it into the set of officially supported .NET languages. I&#39;ve noted &lt;a href=&quot;http://iodyne.blogspot.com/2007/10/f-and-ccr.html&quot;&gt;before&lt;/a&gt; what I liked in general about the language, but readers of this blog might be interested in what it offers in the sort of space that CCR plays in.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Immutability. In common with many functional languages the default syntactic declaration of a &#39;variable&#39; is immutable. Immutability is a &lt;a href=&quot;http://www.bluebytesoftware.com/blog/2007/11/17/ImmutableTypesCanCopyTheWorldSafely.aspx&quot;&gt;generally useful property&lt;/a&gt; in concurrent programming and message-passing systems in particular. F# makes it simple to both declare types (records) and instances of them in a way well-suited to message-passing.&lt;/li&gt; &lt;li&gt;Composition. Functional languages tend to compose and decompose solutions very well (see this &lt;a href=&quot;http://www.math.chalmers.se/~rjmh/Papers/whyfp.html&quot;&gt;classic introduction&lt;/a&gt;). This ability helps factor out a lot of concurrent machinery, whilst still exploiting it. In fact, &lt;a href=&quot;http://armstrongonsoftware.blogspot.com/&quot;&gt;Joe Armstrong&lt;/a&gt; called this &#39;Abstracting out Concurrency&#39; in his &lt;a href=&quot;http://www.erlang.org/download/armstrong_thesis_2003.pdf&quot;&gt;PhD thesis&lt;/a&gt;, and Erlang programs, whilst naturally concurrent, tend to make heavy use of these common patterns.&lt;/li&gt; &lt;li&gt;The latest version of F# contains support for &#39;workflows&#39;, which are very similar in concept to CCR iterators, although an entirely different implementation under the covers. &lt;a href=&quot;http://www.strangelights.com/blog&quot;&gt;Robert Pickering&#39;s blog&lt;/a&gt; has covered these in a &lt;a href=&quot;http://www.strangelights.com/blog/archive/2007/09/29/1597.aspx&quot;&gt;recent series of tutorials&lt;/a&gt;, as well the Erlang-style message-passing approach (something akin to one-time CCR receivers in a read-process loop) it supports.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Incidentally, I read Robert&#39;s book, &lt;a href=&quot;http://www.apress.com/book/view/1590597575&quot;&gt;Foundations of F#&lt;/a&gt; as my first foray into the language. I thought the book was pretty good, but felt (as an FP novice) that it might have benefited more by explaining a little more about FP style and accumulated good practice. Anyway, since then I have also read &lt;a href=&quot;http://www.apress.com/book/view/159059620x&quot;&gt;Practical OCaml&lt;/a&gt;, since F# aims to be compatible with a subset of OCaml. If you&#39;re considering either, my personal recommendation would be read the OCaml book first, and then read Foundations, since the former does a better job of introducing functional programming and the latter provides solid examples of integration with the existing BCL.&lt;/p&gt; &lt;p&gt;I&#39;ve also been working on very lightweight COM-based C++ library for Erlang-style message-passing and task distribution over the native Win32 thread-pool. It&#39;s an ATL-style solution i.e. headers only and I&#39;ll blog a little more about this in future.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/1798211084169858799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/1798211084169858799' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/1798211084169858799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/1798211084169858799'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/12/bits-and-pieces.html' title='Bits and Pieces'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-2665175369271207680</id><published>2007-10-19T07:09:00.001+10:00</published><updated>2007-10-19T07:09:22.745+10:00</updated><title type='text'>F# Goes &amp;#39;Official&amp;#39;</title><content type='html'>&lt;p&gt;&lt;a href=&quot;http://www.bluebytesoftware.com/blog/2007/10/17/WelcomingFToTheFamily.aspx&quot;&gt;Joe Duffy points to the announcement&lt;/a&gt; that the Developer Division at Microsoft is folding F# into the &#39;official&#39; set of supported .NET languages. This is great news.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/2665175369271207680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/2665175369271207680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2665175369271207680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2665175369271207680'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/10/f-goes.html' title='F# Goes &amp;#39;Official&amp;#39;'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-4935167791304597570</id><published>2007-10-17T23:35:00.001+10:00</published><updated>2007-10-17T23:35:10.215+10:00</updated><title type='text'>Hiring...</title><content type='html'>&lt;p&gt;I don&#39;t normally write about my job, so I&#39;m going to write about a different one that could be yours...&lt;/p&gt; &lt;p&gt;My team has vacancies. We design, develop and support equity-derivatives trading systems for one of Australia&#39;s foremost financial institutions for markets at home and abroad.&amp;nbsp;You&#39;d like to work in a small, highly-skilled team of software developers and have some or all of the following:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Strong C++ and optionally VB6 and/or .NET&lt;/li&gt; &lt;li&gt;Significant experience of multi-threaded server application development&lt;/li&gt; &lt;li&gt;SQL experience (preferably SQL Server)&lt;/li&gt; &lt;li&gt;A solid understanding of IP-based communication protocols&lt;/li&gt; &lt;li&gt;A working knowledge of equity-derivative products&lt;/li&gt; &lt;li&gt;A working knowledge of client-side development&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;You&amp;nbsp;will be a self-starter who can work with minimum supervision on projects from inception through delivery and onto support, across the various architectural tiers. You will be comfortable communicating with the key business stake-holders, primarily traders and business managers and be focused on delivering solutions that meet their needs.&lt;/p&gt; &lt;p&gt;Successful applicants would fill vacancies at our Sydney offices and should hold either Australian Citizenship or Permanent Residence. (There are opportunities abroad also).&lt;/p&gt; &lt;p&gt;If you&#39;re interested, please drop me a line via my gmail address (nagunn at ...) and we can take it from there.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/4935167791304597570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/4935167791304597570' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/4935167791304597570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/4935167791304597570'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/10/hiring.html' title='Hiring...'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-3225999729318784082</id><published>2007-10-17T22:10:00.001+10:00</published><updated>2007-10-17T22:10:11.424+10:00</updated><title type='text'>F# and Message-Passing</title><content type='html'>&lt;p&gt;My inexperience with F# has caught me out. &lt;a href=&quot;http://www.strangelights.com/blog&quot;&gt;Robert Pickering&lt;/a&gt; has an &lt;a href=&quot;http://www.strangelights.com/blog/archive/2007/09/29/1597.aspx&quot;&gt;article on asynchronous workflows&lt;/a&gt; (similar concept to&amp;nbsp;CCR iterators)&amp;nbsp;in which he mentions a forthcoming article on &#39;mailboxes&#39;, the message-passing feature I said didn&#39;t exist. I look forward to it.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/3225999729318784082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/3225999729318784082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3225999729318784082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3225999729318784082'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/10/f-and-message-passing.html' title='F# and Message-Passing'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-6530381843926895740</id><published>2007-10-10T22:30:00.001+10:00</published><updated>2007-10-10T22:30:36.577+10:00</updated><title type='text'>Why COM STAs aren&amp;#39;t completely awful</title><content type='html'>&lt;p&gt;...and &lt;a href=&quot;http://www.bluebytesoftware.com/blog/2007/10/09/LifeLessonsFromMrCOMSTA.aspx&quot;&gt;why productivity and pragmatism are important too&lt;/a&gt;. The last two paragraphs are especially interesting.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/6530381843926895740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/6530381843926895740' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/6530381843926895740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/6530381843926895740'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/10/why-com-stas-aren-completely-awful.html' title='Why COM STAs aren&amp;#39;t completely awful'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-8515573735845452461</id><published>2007-10-10T22:18:00.001+10:00</published><updated>2007-10-10T22:18:59.323+10:00</updated><title type='text'>F# and DSS</title><content type='html'>&lt;p&gt;So I rushed ahead of myself a bit and though that I&#39;d try and implement a DSS service in F#. I&#39;ve posted below what I think is the equivalent code for the default DSS service you get when you create a new DSS simple service project. There are three salient points:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;I&#39;ve collapsed the *Types and *Service into a single file.&lt;/li&gt; &lt;li&gt;The support for CCR iterators in the handler methods is a little bit of a hack (my hack).&lt;/li&gt; &lt;li&gt;It doesn&#39;t work. It doesn&#39;t even compile.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;(3) is clearly the most salient point. DSS requires that the Contract class in a service namespace expose a string literal called &#39;Identifier&#39; that contains the contract URI. Unfortunately, the code listed below doesn&#39;t expose a string literal but rather a read-only property. CLR aficionados will know that the difference is that clients that refer to &#39;Contract.Identifier&#39;&amp;nbsp;via a literal end up with that literal in their own assembly so that if that literal changes in the source assembly, pre-existing dependent assemblies don&#39;t reflect that change.&lt;/p&gt; &lt;p&gt;[BTW, don&#39;t change contract identifiers&amp;nbsp;like this. Treat them as web-shaped GUIDs].&lt;/p&gt; &lt;p&gt;Unfortunately, &lt;a href=&quot;http://cs.hubfs.net/forums/permalink/3732/3733/ShowThread.aspx#3733&quot;&gt;F# does not currently support const literals&lt;/a&gt;. So you cannot currently write DSS services in F#. Which is a shame because I think the code could be a slight improvement on the&amp;nbsp;C# equivalent.&lt;/p&gt; &lt;p&gt;Incidentally, it doesn&#39;t compile simply because of the use of Contract.Identifier in the ContractAttribute. As a read-only property, this is a runtime evaluation, not a compile-time one so cannot be used in an attribute constructor. This can be fixed by just replacing the symbolic property with its literal value. However, the DSS runtime still fails to find a Contract class of the right shape.&lt;/p&gt; &lt;p&gt;There are some differences also in the implementation of the handler methods, due to the current limitations of &lt;a href=&quot;http://blogs.msdn.com/dsyme/archive/2007/09/22/some-details-on-f-computation-expressions-aka-monadic-or-workflow-syntax.aspx&quot;&gt;computation expressions&lt;/a&gt;, the primary one being&amp;nbsp;(approximately) that such expressions can only yield results directly - you can&#39;t write &#39;regular&#39; code between yields. The workaround for&amp;nbsp;this is to yield functions that contain the regular code and each return an ITask, then have another computation expression that yields the result of those functions. The following snippets from an F# file of CCR helpers illustrate this:&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;#light&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Ccr.Core&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; deref (x : seq&amp;lt;unit &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; ITask&amp;gt;) = (seq { &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;for&lt;/span&gt; f &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;in&lt;/span&gt; x &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;do&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; f() }).GetEnumerator()&lt;br&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; handler x = Arbiter.FromHandler(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; Handler(x))&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; receive&amp;lt;&#39;a&amp;gt; persist (port : Port&amp;lt;&#39;a&amp;gt;) handler = &lt;br /&gt;    Arbiter.Receive(persist, port, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; Handler&amp;lt;&#39;a&amp;gt;(handler))&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; receive_one&amp;lt;&#39;a&amp;gt; (port : Port&amp;lt;&#39;a&amp;gt;) = receive &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt; port &lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; receive_many&amp;lt;&#39;a&amp;gt; (port : Port&amp;lt;&#39;a&amp;gt;) = receive &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt; port &lt;br /&gt;&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; receive_with_iterator&amp;lt;&#39;a&amp;gt; persist (port : Port&amp;lt;&#39;a&amp;gt;) handler =&lt;br /&gt;    Arbiter.ReceiveWithIterator(persist, port, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; IteratorHandler&amp;lt;&#39;a&amp;gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt;(a) &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;br&gt;        deref(handler(a))))&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; receive_one_with_iterator&amp;lt;&#39;a&amp;gt; (port : Port&amp;lt;&#39;a&amp;gt;) = &lt;br /&gt;    receive_with_iterator &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt; port&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; receive_many_with_iterator&amp;lt;&#39;a&amp;gt; (port : Port&amp;lt;&#39;a&amp;gt;) = &lt;br /&gt;    receive_with_iterator &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt; port&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; activate_many taskQueue tasks = &lt;br /&gt;    Arbiter.Activate(taskQueue, [| &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;for&lt;/span&gt; t &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;in&lt;/span&gt; tasks &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; t :&amp;gt; ITask |] )&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; activate taskQueue task = &lt;br /&gt;    activate_many taskQueue [| task |]&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; ( &amp;amp;= ) taskQueue task = &lt;br /&gt;    activate taskQueue task&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And here&#39;s an example of using them&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;let&lt;/span&gt; port = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; Port&amp;lt;int&amp;gt;()&lt;br /&gt;&lt;/pre&gt;&lt;pre class=&quot;code&quot;&gt;taskQueue &amp;amp;= (receive_many_with_iterator port (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; i &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;br /&gt;    print_endline (&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Triggered.&quot;&lt;/span&gt;)&lt;br /&gt;    seq {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt;() &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            receive_one port (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; i &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; print_endline (i.ToString()))&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt;() &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;br /&gt;&lt;/span&gt;            receive_one port (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; i &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; print_endline (i.ToString()))&lt;br /&gt;    }))&lt;br /&gt;&lt;br /&gt;port.Post(1)&lt;br /&gt;port.Post(2)&lt;br&gt;port.Post(3) &lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Anyway, I digress. Here&#39;s the code for the service. My F# experience is minimal, so I&#39;d be happy to hear about any improvements to any of this code.&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;#light&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;namespace&lt;/span&gt; Iodyne.Drivers.Tcp.Connection&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System.ComponentModel&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System.Net&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; System.Net.Sockets&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Ccr.Core&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Dss.Core.Attributes&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Dss.ServiceModel.Dssp&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Microsoft.Dss.ServiceModel.DsspServiceBase;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; W3C.Soap&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;open&lt;/span&gt; Ccradaptors;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;type&lt;/span&gt; Contract = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;br /&gt;&lt;/span&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; Identifier = &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;http://iodyne.blogspot.com/2007/10/driver/tcp/connection&quot;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;[&amp;lt;DataContract&amp;gt;]&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;type&lt;/span&gt; State = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;br /&gt;&lt;/span&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt;() = {}&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;end&lt;br /&gt;&lt;br /&gt;type&lt;/span&gt; Get = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;br /&gt;&lt;/span&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;inherit&lt;/span&gt; Get&amp;lt;GetRequestType, PortSet&amp;lt;State, Fault&amp;gt;&amp;gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt;() = {}&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt;(body : GetRequestType) = &lt;br /&gt;        { &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;inherit&lt;/span&gt; Get&amp;lt;GetRequestType, PortSet&amp;lt;State, Fault&amp;gt;&amp;gt;(body) }&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt;(body : GetRequestType, response : PortSet&amp;lt;State, Fault&amp;gt;) = &lt;br /&gt;        { &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;inherit&lt;/span&gt; Get&amp;lt;GetRequestType, PortSet&amp;lt;State, Fault&amp;gt;&amp;gt;(body, response) }&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;[&amp;lt;ServicePort&amp;gt;]&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;type&lt;/span&gt; Operations = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;inherit&lt;/span&gt; PortSet&amp;lt;DsspDefaultLookup, DsspDefaultDrop, Get&amp;gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt;() = {}&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;end&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;[&amp;lt;DisplayName(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;TcpConnection&quot;&lt;/span&gt;); &lt;br /&gt;  Description(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;TcpDriver Connection Service&quot;&lt;/span&gt;); &lt;br /&gt;  ContractAttribute(Contract.Identifier)&amp;gt;]&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;type&lt;/span&gt; Service = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;br /&gt;&lt;/span&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;inherit&lt;/span&gt; DsspServiceBase &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;as&lt;/span&gt; base&lt;br /&gt;    [&amp;lt;ServicePort(AllowMultipleInstances = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;val&lt;/span&gt; mainPort : Operations&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;val&lt;/span&gt; state : State&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt;(creationPort : DsspServiceCreationPort) = {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;inherit&lt;/span&gt; DsspServiceBase(creationPort) ;&lt;br /&gt;        state = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; State()&lt;br /&gt;        mainPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; Operations() }&lt;br /&gt;    &lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;override&lt;/span&gt; this.Start() = &lt;br /&gt;        base.Start()&lt;br /&gt;    &lt;br /&gt;    [&amp;lt;ServiceHandler(ServiceHandlerBehavior.Concurrent)&amp;gt;]&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;member&lt;/span&gt; this.GetHandler(get : Get) = &lt;br /&gt;        enumerate &lt;br /&gt;            (seq {&lt;br /&gt;                 &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; (handler (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;fun&lt;/span&gt; () &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;-&amp;gt;&lt;/span&gt; get.ResponsePort.Post(this.state)))&lt;br /&gt;            })&lt;br /&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;end&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/8515573735845452461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/8515573735845452461' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8515573735845452461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8515573735845452461'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/10/f-and-dss.html' title='F# and DSS'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-1472765017062471406</id><published>2007-10-08T11:41:00.001+10:00</published><updated>2007-10-08T11:41:54.579+10:00</updated><title type='text'>F# and CCR</title><content type='html'>&lt;p&gt;I mentioned &lt;a href=&quot;http://iodyne.blogspot.com/2007/07/my-introduction-to-erlang.html&quot;&gt;a while back&lt;/a&gt;&amp;nbsp;that I&#39;d read Joe Armstrong&#39;s PhD thesis on building reliable distributed systems. Early on, Joe introduces &lt;a href=&quot;http://www.erlang.org/&quot;&gt;Erlang,&lt;/a&gt; a language he and his team designed at Ericsson to build large-scale, fault-tolerant, concurrent systems.&lt;/p&gt; &lt;p&gt;I&#39;ve no background at all in &lt;a href=&quot;http://en.wikipedia.org/wiki/Functional_languages&quot;&gt;functional languages,&lt;/a&gt; but I was struck by&amp;nbsp;4 things (in no particular order):&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The code seemed to have hit a sweet-spot of readability and brevity. It&#39;s a compact syntax.&lt;/li&gt; &lt;li&gt;The support of functions as first-class types (a feature of functional languages), allowed for some simple but powerful constructs. &lt;/li&gt; &lt;li&gt;A lot of type inference (and a lot less typing!)&lt;/li&gt; &lt;li&gt;Language support for message-passing primitives.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;I won&#39;t expand particularly on these right now, but some of these features have crept into C#, notably limited type inference (i.e. the var keyword) and lambda functions (via succinct syntax for anonymous delegates). &lt;/p&gt; &lt;p&gt;Anyway, whilst reading round Erlang and functional languages in general, I discovered &lt;a href=&quot;http://research.microsoft.com/fsharp/fsharp.aspx&quot;&gt;F#&lt;/a&gt;, a research language from the Microsoft Research group at Cambridge University, England.&amp;nbsp; F# is a CLR language, with strong functional influences but with support also for imperative and object-oriented programming. (One of the principal developers, Don Syme, was one of the guys who worked out how to do generics on the CLR).&lt;/p&gt; &lt;p&gt;F# shares with Erlang the first 3 points above. And that got me thinking that the CCR, integrated through the F# could provide the fourth. You can use the CCR directly from F#, but wrapper functions make it easier still to add powerful concurrency and co-ordination support for task-based programming directly into F# in a natural way, and I&#39;ll blog about these in forthcoming posts.&lt;/p&gt; &lt;p&gt;BTW, &lt;a href=&quot;http://erlangdotnet.net/2007/09/why-compile-erlang-for-clr.html&quot;&gt;someone is building Erlang.NET&lt;/a&gt;!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/1472765017062471406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/1472765017062471406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/1472765017062471406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/1472765017062471406'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/10/f-and-ccr.html' title='F# and CCR'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-3308422526806565015</id><published>2007-09-20T21:40:00.001+10:00</published><updated>2007-09-20T21:40:54.954+10:00</updated><title type='text'>Crunched</title><content type='html'>&lt;p&gt;I was asked on the Australian DotNet Mailing List (send &quot;subscribe dotnet&quot; in the body of the email to: &lt;a href=&quot;mailto:imailsrv@stanski.com&quot;&gt;imailsrv@stanski.com&lt;/a&gt;) if I could provide the CCR posts as a document, to make it easier&amp;nbsp;to print off.&amp;nbsp;Sort of. My host (blogger) doesn&#39;t support downloads as far as I can tell, and Windows Live Writer (Beta) has no facility for saving posts as word documents, so it was a cut-and-paste job in the end.&lt;/p&gt; &lt;p&gt;The document can be found on &lt;a href=&quot;http://www.filecrunch.com/file/~cmkxky&quot;&gt;FileCrunch&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It&#39;s a little rough and ready, in particular the spacing of the code samples is not all it could be. Any hints or tips on this greatly received.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/3308422526806565015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/3308422526806565015' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3308422526806565015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3308422526806565015'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/09/crunched.html' title='Crunched'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-8467371506666655042</id><published>2007-09-17T21:46:00.001+10:00</published><updated>2007-09-17T21:46:57.611+10:00</updated><title type='text'>Innovation book</title><content type='html'>&lt;p&gt;I&#39;ve started reading Scott Berkun&#39;s &lt;a href=&quot;http://www.amazon.com/Myths-Innovation-Scott-Berkun/dp/0596527055&quot;&gt;&#39;The Myths of Innovation&#39;&lt;/a&gt;. It&#39;s an interesting read, exposing the cultural myths that surround ideas, those who have them and those who capitalise on them. It&#39;s also an O&#39;Reilly book without an animal on the front!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/8467371506666655042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/8467371506666655042' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8467371506666655042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8467371506666655042'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/09/innovation-book.html' title='Innovation book'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-6025696648450559758</id><published>2007-09-12T23:11:00.001+10:00</published><updated>2007-09-12T23:11:21.480+10:00</updated><title type='text'>DSS Optimizations</title><content type='html'>&lt;p&gt;I was looking at some of the code generated by the &lt;em&gt;dssproxy&lt;/em&gt; tool. When you define a service (by specifying types and operations), the dssproxy tool takes your service assembly and generates two associated assemblies, a &lt;em&gt;proxy&lt;/em&gt; and a &lt;em&gt;transform&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;The proxy is the assembly that clients of the service use to send and receive messages. It contains representations of the service types that can also serialize and deserialize themselves for transmission. I noticed that these representations have a small inefficiency on how they deal with the deserialization of List&amp;lt;T&amp;gt;s. Prior to the state of each T is the count of all Ts in the list. This information is used to determine how many Ts to expect in the stream. It could also be used to construct the list with an initial capacity, to avoid excessive re-allocation and copying for large numbers of T. The generated code doesn&#39;t currently do this. Fortunately, you do have the source for the proxies, so you can change it yourself if it really matters.&lt;/p&gt; &lt;p&gt;Incidentally, the transform assembly is used in the same app-domain as the&amp;nbsp;service&amp;nbsp;to transform the proxy types (e.g. the ones that arrive off the wire) into the original types as defined in your service assembly. The transform suffers the same small issue regarding collections.&lt;/p&gt; &lt;p&gt;The other thing I noticed was that DSS maintains tables (of type Dictionary&amp;lt;K,V&amp;gt;) keyed on Type. One place these tables are used is in looking up the correct transform for a proxy instance. Given an object of some proxy type, it calls GetType() and uses the resulting Type object to look up the transform instance.&lt;/p&gt; &lt;p&gt;As &lt;a href=&quot;http://blogs.msdn.com/vancem/archive/2006/10/01/779503.aspx&quot;&gt;Vance Morrison pointed out&lt;/a&gt;, in his excellent blog, if all you need is a type look-up then it&#39;s more efficient to use a &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/system.runtimetypehandle.aspx&quot;&gt;RuntimeTypeHandle&lt;/a&gt;. It&#39;s a simple struct that just contains an IntPtr, so it consumes less space than a Type reference and as a struct doesn&#39;t participate in garbage collection cycles. As he points out later in the article, using the handle instead of the type will reap more benefits still once certain JIT optimizations are released.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/6025696648450559758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/6025696648450559758' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/6025696648450559758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/6025696648450559758'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/09/dss-optimizations.html' title='DSS Optimizations'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-3492365820513607145</id><published>2007-08-23T07:33:00.001+10:00</published><updated>2007-08-23T07:33:59.190+10:00</updated><title type='text'>All (not) my own work</title><content type='html'>&lt;p&gt;I&#39;ve not posted much of my own recently. Outside of work (which has been getting&amp;nbsp;a little hectic lately), I&#39;ve been working on a small, sample project that will hopefully be a good segway into &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb483067.aspx&quot;&gt;Distributed Software Services&lt;/a&gt;, which provides an application model for highly-concurrent, message-passing based programs in .NET. &lt;/p&gt; &lt;p&gt;That will come after I finish off covering the remaining CCR features, specifically &lt;a href=&quot;http://msdn2.microsoft.com/EN-US/library/bb648750.aspx&quot;&gt;causalities&lt;/a&gt;&amp;nbsp;and maybe &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb648751.aspx&quot;&gt;interop&lt;/a&gt;. I&#39;d be happy to hear any suggestions for future posts that you think I&#39;ve not covered, or not covered sufficiently well. I&#39;m aware that after building up CCR iterators, I rushed through them rather quickly.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/3492365820513607145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/3492365820513607145' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3492365820513607145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3492365820513607145'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/all-not-my-own-work.html' title='All (not) my own work'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-2526865679181890282</id><published>2007-08-22T23:23:00.001+10:00</published><updated>2007-08-22T23:23:41.520+10:00</updated><title type='text'>Just wing it</title><content type='html'>&lt;p&gt;Courtesy of &lt;a href=&quot;http://microsoftdev.blogspot.com/2007/08/excellent-talk-on-concurrency.html&quot;&gt;Kiran&lt;/a&gt;, an interesting &lt;a href=&quot;http://ptolemy.eecs.berkeley.edu/~eal/videos/EALatMSR_Jan07/lecture.htm&quot;&gt;presentation&lt;/a&gt; by &lt;a href=&quot;http://ptolemy.eecs.berkeley.edu/~eal/&quot;&gt;Edward A. Lee&lt;/a&gt; on why shared memory is broken and what is needed instead to &#39;make concurrency mainstream&#39;.&lt;/p&gt; &lt;p&gt;[I couldn&#39;t get it to go under Firefox, but IE had no bother. You may get different results.]&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/2526865679181890282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/2526865679181890282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2526865679181890282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2526865679181890282'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/just-wing-it.html' title='Just wing it'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-964284987044519808</id><published>2007-08-16T21:18:00.001+10:00</published><updated>2007-08-16T21:18:28.816+10:00</updated><title type='text'>Newsqueak and Payback Time</title><content type='html'>&lt;p&gt;An interesting &lt;a href=&quot;http://video.google.com/videoplay?docid=810232012617965344&quot;&gt;video&lt;/a&gt;&amp;nbsp;presenting Newsqueak, another language with message-passing built in. And Joe Armstrong &lt;a href=&quot;http://www.pragmaticprogrammer.com/articles/erlang.html&quot;&gt;looks forward&lt;/a&gt; to a golden era for Erlang developers. Am I just looking harder or is message-passing gaining momentum nowadays?&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/964284987044519808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/964284987044519808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/964284987044519808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/964284987044519808'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/newsqueak-and-payback-time.html' title='Newsqueak and Payback Time'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-2348561423856265837</id><published>2007-08-16T09:49:00.000+10:00</published><updated>2007-08-16T09:53:29.746+10:00</updated><title type='text'>I&#39;m back</title><content type='html'>Obviously. Blogger suspended my account as their anti-spam bot identified this content as spam. So much for heuristics. Or maybe not depending on your point of view.</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/2348561423856265837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/2348561423856265837' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2348561423856265837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2348561423856265837'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/im-back.html' title='I&#39;m back'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-5432483944199288300</id><published>2007-08-12T00:42:00.001+10:00</published><updated>2007-08-12T00:42:22.557+10:00</updated><title type='text'>CCR 101 - Part 9: Iterators</title><content type='html'>&lt;p&gt;&lt;em&gt;Iterators (&lt;/em&gt;or &lt;em&gt;Iterative Tasks&lt;/em&gt; in CCR parlance) are one of the standout features of the CCR. Their design and implementation is an imaginative fusion of the message-passing paradigm and the iterator functionality introduced in C# 2.0. But whether or not you choose to sit and admire the aesthetics of the CCR, you would probably agree that it is what they enable that is truly impressive - &lt;em&gt;the ability to write a logical sequence of actions, within a single method, without ever blocking the thread between those actions&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Now obviously the strength of this functionality really shines through when each action results in some form of asynchronous I/O, e.g. a web request or&amp;nbsp;a database write. In this case, the thread is freed up to service other tasks whilst the I/O completes, before returning to the next action in the sequence. But remember, in our CCR-based message-passing world, pretty much &lt;em&gt;all&lt;/em&gt; I/O is performed asynchronously even if those messages are passed between CPU-bound services in the same process. &lt;/p&gt; &lt;h5&gt;C# 2.0 Iterators: A (quick) recap.&lt;/h5&gt; &lt;p&gt;The fundamental idea of the iterator functionality is to allow&amp;nbsp;the developer to present an enumerable&amp;nbsp;list to some other code without the explicit population or implementation of that list. Here&#39;s a sample that presents the list of the first 5 primes.&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0901&lt;/span&gt; {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; p &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;in&lt;/span&gt; FirstFivePrimes()) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(p.ToString());&lt;br /&gt;        }&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt;&amp;gt; FirstFivePrimes() {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; 1;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; 2;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; 3;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; 5;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; 7;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Very contrived, and next to useless, but let&#39;s just examine the salient points. The first is that the client can just write a simple &lt;em&gt;foreach&lt;/em&gt; loop. This in itself is just a shorthand (and compiler-generated) way of writing:&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0902&lt;/span&gt; {&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt;&amp;gt; pe = FirstFivePrimes().GetEnumerator();&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;while&lt;/span&gt; (pe.MoveNext())&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(pe.Current.ToString());&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Elided...&lt;br /&gt;&lt;/span&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Now, the &lt;em&gt;really&lt;/em&gt; clever code-generation is not in &lt;em&gt;Main()&lt;/em&gt;, but in &lt;em&gt;FirstFivePrimes()&lt;/em&gt;. The compiler generates a new class for this method that acts as a state machine. &lt;em&gt;GetEnumerator()&lt;/em&gt; returns a new instance of this class. The client moves through the state by calling &lt;em&gt;MoveNext()&lt;/em&gt; on the enumerator and the generated class exposes this state through the &lt;em&gt;Current&lt;/em&gt; value. Each &lt;em&gt;&#39;yield return X&#39;&lt;/em&gt; statement sets the new state of the instance.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;There are other, much better articles on iterators, in &lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/04/05/C20/#S1&quot;&gt;MSDN Magazine&lt;/a&gt; and on &lt;a href=&quot;http://blogs.msdn.com/matt_pietrek/archive/2004/07/26/197242.aspx&quot;&gt;Matt Pietrek&#39;s blog&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Iterators the CCR way.&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;In the Coordination and Concurrency Runtime, iterators are used to return &lt;em&gt;tasks&lt;/em&gt; that are then scheduled for execution. The CCR calls &lt;em&gt;MoveNext()&lt;/em&gt; to execute the first task, which will execute all the code in the iterator method up to and including the first yield statement. And here&#39;s another clever bit. By yielding arbitrations (e.g. join or choice), which are themselves tasks, you can logically block until the arbitration completes. In the meantime, the dispatcher thread just goes off and processes other pending tasks.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Let&#39;s take a look at an example. The following code crawls the front page of this blog&#39;s home site for links to MSDN blogs. It then issues requests to fetch each of these blogs and prints out how many it successfully retrieved and how many failed.&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0903&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt; dispatcher = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt;()) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; taskQueue = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;IteratorSample&quot;&lt;/span&gt;, dispatcher)) {&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; url = &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;http://iodyne.blogspot.com&quot;&lt;/span&gt;;&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(taskQueue, &lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.FromIteratorHandler(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; { &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; DoWork(url); }));&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;IEnumerator&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ITask&lt;/span&gt;&amp;gt; DoWork(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; url) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;PortSet&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebResponse&lt;/span&gt;, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt;&amp;gt; webResult = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;PortSet&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebResponse&lt;/span&gt;, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt;&amp;gt;();&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebRequest&lt;/span&gt; webRequest = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebRequest&lt;/span&gt;.Create(url);&lt;br /&gt;        webRequest.BeginGetResponse(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;IAsyncResult&lt;/span&gt; iar) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;try&lt;/span&gt; {&lt;br /&gt;                webResult.Post(webRequest.EndGetResponse(iar));                &lt;br /&gt;            } &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt; e) {&lt;br /&gt;                webResult.Post(e);&lt;br /&gt;            }&lt;br /&gt;        }, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;null&lt;/span&gt;);&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebResponse&lt;/span&gt; webResponse = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;null&lt;/span&gt;;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Choice(webResult,&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebResponse&lt;/span&gt; wr) {&lt;br /&gt;                webResponse = wr;&lt;br /&gt;            },&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt; e) {&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(e);&lt;br /&gt;            });&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;if&lt;/span&gt; (webResponse == &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;null&lt;/span&gt;)&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; body = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;StreamReader&lt;/span&gt;(webResponse.GetResponseStream()).ReadToEnd();&lt;br /&gt;        webResponse.Close();&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Regex&lt;/span&gt; hrefRegex = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Regex&lt;/span&gt;(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;http\\:\\/\\/blogs\\.msdn\\.com\\/[^&#39;\&quot;\&quot;]*&quot;&lt;/span&gt;, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;RegexOptions&lt;/span&gt;.IgnoreCase);&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;MatchCollection&lt;/span&gt; mc = hrefRegex.Matches(body);&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;PortSet&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt;&amp;gt; multiPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;PortSet&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt;&amp;gt;();&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;foreach&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Match&lt;/span&gt; m &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;in&lt;/span&gt; mc) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; murl = m.ToString();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebRequest&lt;/span&gt; murlRequest = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WebRequest&lt;/span&gt;.Create(murl);&lt;br /&gt;            murlRequest.BeginGetResponse(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;IAsyncResult&lt;/span&gt; iar) {&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;try&lt;/span&gt; {&lt;br /&gt;                    murlRequest.EndGetResponse(iar).Close();&lt;br /&gt;                    multiPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;                } &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;catch&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt; e) {&lt;br /&gt;                    multiPort.Post(e);&lt;br /&gt;                }&lt;br /&gt;            }, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;null&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.MultipleItemReceive(multiPort, mc.Count,&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ICollection&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; wr, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ICollection&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Exception&lt;/span&gt;&amp;gt; ex) {&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(wr.Count.ToString() + &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot; succeeded. &quot;&lt;/span&gt; + ex.Count.ToString() + &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot; failed.&quot;&lt;/span&gt;);&lt;br /&gt;            });&lt;br /&gt;&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;yield&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;break&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;The bulk of the work is done within the iterator. It only yields two tasks, the first of which is a &lt;em&gt;Choice&lt;/em&gt;, that detects whether the initial page fetch worked at all. If it didn&#39;t, we have no WebResponse and we &lt;em&gt;yield break&lt;/em&gt;, which exits the iterator. If we did get a response then we parse the page for the MSDN blogs and then for each match we issue another asynchronous web request concurrently.&amp;nbsp;Each successful response results in an &lt;em&gt;EmptyValue&lt;/em&gt; signal, each failure an exception. Finally we yield to a &lt;em&gt;MultipleItemReceive&lt;/em&gt; and output how many of these requests succeeded and how many failed. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;This highly I/O-bound iterator only consumes threads for a tiny fraction of its elapsed time, mostly when doing the initial page parse and yet I still got to code it up in a basically sequential fashion.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I&#39;ll add a few further notes to this is a subsequent post.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/5432483944199288300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/5432483944199288300' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/5432483944199288300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/5432483944199288300'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/ccr-101-part-9-iterators.html' title='CCR 101 - Part 9: Iterators'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-8846212913036578881</id><published>2007-08-10T00:02:00.001+10:00</published><updated>2007-08-10T00:02:45.147+10:00</updated><title type='text'>More Concurrency Reading...</title><content type='html'>&lt;p&gt;I just haven&#39;t had the time this week to write the CCR Iterators post. A hard deadline at work means that spare capacity is at a premium right now, and likely to be in the near future. In the meantime, a few articles related to concurrency. Probably preaching to the converted...&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&quot;http://www.gotw.ca/publications/concurrency-ddj.htm&quot;&gt;One from Herb Sutter&lt;/a&gt;. A bit out of date now, but not dated. Also, a &lt;a href=&quot;http://acmqueue.com/modules.php?name=Content&amp;amp;pa=showpage&amp;amp;pid=332&quot;&gt;follow-up&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;An &lt;a href=&quot;http://research.microsoft.com/~simonpj/papers/stm/beautiful.pdf&quot;&gt;interesting introduction to Software Transactional Memory&lt;/a&gt; by Simon Peyton-Jones. &lt;/li&gt;&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/8846212913036578881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/8846212913036578881' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8846212913036578881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8846212913036578881'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/more-concurrency-reading.html' title='More Concurrency Reading...'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-3095975171069428938</id><published>2007-08-06T00:19:00.001+10:00</published><updated>2007-08-08T21:55:30.643+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>Patrick Dussud on CLR Garbage Collection</title><content type='html'>&lt;p&gt;An interesting &lt;a href=&quot;http://channel9.msdn.com/Showpost.aspx?postid=329808&quot;&gt;video&lt;/a&gt; on &lt;a href=&quot;http://channel9.msdn.com/&quot;&gt;Channel9&lt;/a&gt; featuring &lt;a href=&quot;http://www.microsoft.com/presspass/exec/de/Dussud/default.mspx&quot;&gt;Patrick Dussud&lt;/a&gt;, now chief architect (and one-time principal developer) of the .NET garbage collector. There are lots of smart cookies working in the software industry, many without much fanfare. Kudos to Microsoft (and Patrick) for putting themselves forward. The rest of us benefit from this kind of effort.&lt;/p&gt; &lt;p&gt;Indirectly, I also re-acquainted myself with Maoni Stephens &lt;a href=&quot;http://blogs.msdn.com/maoni/&quot;&gt;blog&lt;/a&gt; (also CLR GC). Well worth a look for CLR aficionados.&lt;/p&gt; &lt;p&gt;To those readers who maybe waiting for the next instalment of CCR 101, I intend to fulfill my promise to cover Iterators this week, work commitments allowing.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/3095975171069428938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/3095975171069428938' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3095975171069428938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/3095975171069428938'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/08/patrick-dussud-on-clr-garbage.html' title='Patrick Dussud on CLR Garbage Collection'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-2471404440650931237</id><published>2007-07-30T23:45:00.001+10:00</published><updated>2007-08-08T21:55:30.643+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>My Introduction to Erlang</title><content type='html'>&lt;p&gt;I&#39;ve just finished reading &lt;a href=&quot;http://armstrongonsoftware.blogspot.com/&quot;&gt;Joe Armstrong&lt;/a&gt;&#39;s &lt;a href=&quot;http://www.erlang.org/download/armstrong_thesis_2003.pdf&quot;&gt;PhD thesis&lt;/a&gt; entitled &#39;Making reliable distributed systems in the presence of software errors&#39; (this is becoming a bit of a &lt;a href=&quot;http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm&quot;&gt;habit&lt;/a&gt;). &lt;/p&gt; &lt;p&gt;Anyway, I found it very clear and well presented. Although I don&#39;t know much about Erlang or switching systems, what Joe has to say&amp;nbsp;about distributed software architectures has much in common with Decentralized Software Services (&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb483067.aspx&quot;&gt;DSS&lt;/a&gt;). To paraphrase Joe&#39;s summary of the characteristics of &lt;em&gt;Concurrency-Oriented Programming:&lt;/em&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Services are isolated from one another. A fault in one should not &lt;em&gt;adversely&lt;/em&gt; affect another.&lt;/li&gt; &lt;li&gt;Each service has an identifier, and is addressable by it.&lt;/li&gt; &lt;li&gt;There is no shared state between services.&lt;/li&gt; &lt;li&gt;Services interact via &lt;em&gt;asynchronous&lt;/em&gt; messaging, which must be assumed to be unreliable.&lt;/li&gt; &lt;li&gt;Services are units of concurrency. They run independently of one another.&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/2471404440650931237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/2471404440650931237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2471404440650931237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/2471404440650931237'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/07/my-introduction-to-erlang.html' title='My Introduction to Erlang'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-8985770470013238175</id><published>2007-07-30T23:15:00.001+10:00</published><updated>2007-07-30T23:18:53.440+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CCR"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>CCR 101 - Part 8: Dispatchers</title><content type='html'>&lt;p&gt;I&#39;ve not covered the &lt;em&gt;Dispatcher&lt;/em&gt; class before in any detail, and in all the examples so far, I&#39;ve only used &lt;em&gt;DispatcherQueue&lt;/em&gt;s via their default constructor which causes all tasks to be scheduled over the CLR thread-pool. The CCR &lt;em&gt;Dispatcher&lt;/em&gt; class provides a means&amp;nbsp;of scheduling tasks over your own custom thread-pool. &lt;/p&gt; &lt;p&gt;Being in control of the thread-pool creation gives you some control over the properties of the threads themselves (albeit as a homogenous block - you can&#39;t set these properties on individual threads). These include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The name of the threads. This is a useful diagnostic property.&lt;/li&gt; &lt;li&gt;Whether the threads will run in the background. Background threads will not keep the application active, should all the other foreground threads exit.&lt;/li&gt; &lt;li&gt;The priority the threads will run at.&lt;/li&gt; &lt;li&gt;The COM apartment&amp;nbsp;state of the threads. This is useful for interop.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;First though, let&#39;s&amp;nbsp;adapt our &lt;a href=&quot;http://iodyne.blogspot.com/2007/07/ccr-101-part-2-dispatcherqueues-and.html&quot;&gt;first sample&lt;/a&gt; for use with a standard dispatcher:&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0801&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt; dispatcher = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt;()) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; dq = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Default&quot;&lt;/span&gt;, dispatcher)) {&lt;br /&gt;                dq.Enqueue(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Task&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;() {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Hello world.&quot;&lt;/span&gt;);&lt;br /&gt;                }));&lt;br /&gt;            }&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Straightforward enough. First we create our dispatcher. We use the default constructor. This will create a fixed number of threads (more on this later). All threads will run in the foreground at normal priority, their apartment state will be not be set and their names will be empty strings. Notice how we dispose of the dispatcher when we are finished with it. This ensures that all the threads are properly destroyed.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So why use a dispatcher at all? Why not just use a default-constructed DispatcherQueue and schedule items over the CLR thread-pool? Well, you might want to control some of aspects of the thread-pool via the properties discussed above. You might want to isolate your CCR task-execution threads from 3rd-party libraries that use the CLR thread-pool (or even other CCR tasks, via two or more dispatchers).&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Another important reason is that the execution policies which govern how task-execution is constrained &lt;em&gt;only work with custom dispatcher pools&lt;/em&gt;. We&#39;ll have a look at an example of this shortly.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;You might even need the extra performance. Some of the flexibility of the CLR thread-pool - such as its dynamic sizing capabilities - comes at a small performance cost. Dispatcher-based thread-pools have a &lt;em&gt;fixed&lt;/em&gt; number of threads and because there is less management&amp;nbsp;of the threads, they have been observed to be more performant in some situations. Your mileage may very.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;So how many threads in a dispatcher-pool? Well, the default constructor will create 1 thread-per-CPU on a multi-processor box, and two threads on a uniprocessor box. You can use one of the constructor overloads to specify an exact number of threads, or you can set the static &lt;em&gt;Dispatcher.ThreadsPerCpu&lt;/em&gt; property prior to using the default constructor. And even with the overloads you can always pass 0 to the number of threads, and let the CCR work it out for you.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;COM Interop&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;Whilst it might be preferable to have all your application in managed code, there&#39;s a good chance that you still have COM components that form part of your existing application and which you&#39;ll need to interop with in the short term. In principle, if your components are &#39;Both&#39; or &#39;Free&#39; threaded, then you don&#39;t have to do anything - they&#39;ll play happily in the same threads as your tasks without creating any COM proxies, and should be addressable without said proxies from those threads.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If however, those components are marked as &#39;Apartment&#39; then you need to tread carefully (as always). If you create these components on a vanilla dispatcher thread, you&#39;ll get&amp;nbsp;a proxy. When you call across through this proxy, you&#39;ll incur the marshaling cost, but more importantly, the calling thread will be forced to sleep, whilst the recipient thread processes the call. What&#39;s worse, is that in the absence of an appropriate STA thread, the COM runtime will spin one up for you and put the COM object in that thread. In fact, it will spin up &lt;em&gt;only one&lt;/em&gt; and put &lt;em&gt;all&lt;/em&gt; STA instances on that thread, forming another serialization bottleneck.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;What you do about this depends on how you use the COM object. If you can get away with a create-use-destroy model, then you can create &lt;em&gt;n&lt;/em&gt; STA threads under a dispatcher register tasks using that model and just schedule receives to do the work. The following (albeit contrived) example creates 2 STA threads and then posts a receive which creates an instance of the Windows Media Player, calls a method on it and then releases it.&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0802&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt; dispatcher = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt;(&lt;br /&gt;            2, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ThreadPriority&lt;/span&gt;.Normal, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherOptions&lt;/span&gt;.None, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ApartmentState&lt;/span&gt;.STA, &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;STAPool&quot;&lt;/span&gt;)) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; dq = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Default&quot;&lt;/span&gt;, dispatcher)) {&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; signalPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(dq, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, signalPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt; ev) {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;IWMPPlayer&lt;/span&gt; player = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;WindowsMediaPlayerClass&lt;/span&gt;();&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(player.versionInfo);&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Marshal&lt;/span&gt;.ReleaseComObject(player);&lt;br /&gt;                }));&lt;br /&gt;&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; line = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;while&lt;/span&gt; (line != &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;quit&quot;&lt;/span&gt;) {&lt;br /&gt;                    signalPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;                    line = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;If the COM object is long-lived, then you need a different strategy, which basically involves creating single-threaded STA dispatchers and the judicious use of &lt;em&gt;IterativeTasks&lt;/em&gt;, so I shall defer that sample until I&#39;ve covered iterators properly.&lt;/p&gt;&lt;br /&gt;&lt;h5&gt;Task Execution Policies&lt;/h5&gt;&lt;br /&gt;&lt;p&gt;The following examples shows how task execution policies can be used to constrain scheduling. The first generates an int every second, but the receiver takes two seconds to process it. We use a scheduling policy that constrains the queue depth to 1, which effectively means that a newly-arrived item will replace an unprocessed item. If the receiver can&#39;t keep up, it will only have to process the latest item.&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0803&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt; dispatcher = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Dispatcher&lt;/span&gt;(1, &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;PolicyDemo&quot;&lt;/span&gt;)) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; dq = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;(&lt;br /&gt;                &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Default&quot;&lt;/span&gt;, dispatcher, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TaskExecutionPolicy&lt;/span&gt;.ConstrainQueueDepthDiscardTasks, 1)) {&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt;&amp;gt; intPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(dq, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, intPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; i) {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(i.ToString());&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Thread&lt;/span&gt;.Sleep(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TimeSpan&lt;/span&gt;.FromSeconds(2));&lt;br /&gt;                }));&lt;br /&gt;&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; 20; ++i) {&lt;br /&gt;                    intPort.Post(i);&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Thread&lt;/span&gt;.Sleep(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TimeSpan&lt;/span&gt;.FromSeconds(1));&lt;br /&gt;                }&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;You might have noticed that I&#39;ve created a single threaded Dispatcher here. That&#39;s really to force the demo to work. If I use a default dispatcher on the machine I&#39;m currently sitting at, which has a single hyper-threaded CPU, I get two threads, and two threads is enough to process all the items in turn. Even if one thread blocks for two seconds, the other thread is free to process the next item. &lt;/p&gt;&lt;br /&gt;&lt;p&gt;That&#39;s all I want to cover about Dispatchers for now. I&#39;ll come back to them soon when I demonstrate a strategy for dealing with long-running STA objects, but the next topic will be about &lt;em&gt;Iterators&lt;/em&gt; or &lt;em&gt;IterativeTasks&lt;/em&gt;, arguably one of the most powerful features of the CCR.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/8985770470013238175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/8985770470013238175' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8985770470013238175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/8985770470013238175'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/07/ccr-101-part-8-dispatchers.html' title='CCR 101 - Part 8: Dispatchers'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-9199268870638599692</id><published>2007-07-29T00:07:00.001+10:00</published><updated>2007-07-30T23:18:53.441+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CCR"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>CCR 101 - Part 7: Interleave</title><content type='html'>&lt;p&gt;The &lt;em&gt;Interleave&lt;/em&gt; is essentially an arbitration with reader-writer scheduling semantics. It does this by splitting the Receiver tasks it arbitrates into 3 categories:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;em&gt;Concurrent&lt;/em&gt; receivers. Any receivers in this group can be scheduled concurrently with any other receivers from this group, providing no exclusive receivers (see below) are active or pending.  &lt;li&gt;&lt;em&gt;Exclusive&lt;/em&gt; receivers. A receiver from this group will only be scheduled when there are no other exclusive or concurrent receivers active. &lt;li&gt;&lt;em&gt;Teardown&lt;/em&gt; receivers. A receiver in this group will also run exclusively but causes the Interleave to &#39;retire&#39;. Once a receiver in the group has been scheduled, all other receivers are abandoned and will not be scheduled.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Note that none of these categories need have any receivers at all. &lt;/p&gt; &lt;p&gt;There are a few more interesting things about Interleaves:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Exclusive receivers have their order retained. Remember &lt;a href=&quot;http://iodyne.blogspot.com/2007/07/ccr-101-part-4-arbitrations-receivers.html&quot;&gt;how we saw&lt;/a&gt; that a persistent Receive (without an outer arbitration to control the scheduling) would schedule tasks as fast as items arrived, leading to out-of-order processing across multiple threads? Well, by placing that Receiver within the set of exclusive Receivers, the processing will remain in order. This is because the Interleave is concerned with&amp;nbsp;the completion of the Receiver task, not just its scheduling.&lt;/li&gt; &lt;li&gt;Interleaves may be &lt;em&gt;combined&lt;/em&gt;. You can &#39;merge&#39; one interleave with another. Each group (concurrent, exclusive, teardown) is merged and behaves as if you had declared the single more complex interleave.&lt;/li&gt; &lt;li&gt;Interleaves still offer opportunities for deadlock and I&#39;ll&amp;nbsp;cover these in the post that deals with&amp;nbsp;&lt;em&gt;IterativeTasks&lt;/em&gt;, because the use of the latter within the former is where they can occur.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Let&#39;s look at example. This one is more complicated than the others we&#39;ve seen so far and I&#39;ve burnished it with a few comments to help illustrate the salient points. We use the Interleave to protect a counter that increments every second and allows the the client to query the current value. &lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0701&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; dq = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;()) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ManualResetEvent&lt;/span&gt; done = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ManualResetEvent&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;);&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; counter = 0;&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Signal port - indicates the counter should be incremented&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; signalPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Query port - indicates that the counter should be read&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; queryPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Quit port - indicates that the interleave should exit&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; quitPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Declare the interleave&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt; il = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt;(&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TeardownReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, quitPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Finished.&quot;&lt;/span&gt;);&lt;br /&gt;                    done.Set();&lt;br /&gt;                })),&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ExclusiveReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, signalPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    ++counter;&lt;br /&gt;                })),&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ConcurrentReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, queryPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(counter.ToString());&lt;br /&gt;                })));&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Then activate it&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(dq, il);&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Now start a timer that will fire every second, then read the console. An empty&lt;br&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// line causes the program to quit.&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Timer&lt;/span&gt; t = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Timer&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; { signalPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance); })) {&lt;br /&gt;                t.Change(0, 1000);&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; line = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;while&lt;/span&gt; (line.Length &amp;gt; 0) {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;if&lt;/span&gt; (line == &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;q&quot;&lt;/span&gt;)&lt;br /&gt;                        queryPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;                    line = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;                }&lt;br /&gt;                quitPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;            }&lt;br /&gt;            done.WaitOne();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;We create three ports. One carries a request to increment the counter, one to query the counter and one to shutdown. We create our Interleave arbitration over these three ports, then activate it. Then we activate a timer which fires every second, posting a message to the appropriate port when it does so. Then we sit in&amp;nbsp;a loop, reading the console.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now consider, if we wanted to support an extra message that would reset the counter. This requires a new port (in this example at least) and an additional exclusive receiver. I&#39;ve altered the above sample, to show how to do this, highlighting the amendments in bold.&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0702&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; dq = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;()) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ManualResetEvent&lt;/span&gt; done = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ManualResetEvent&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;);&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; counter = 0;&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Signal port - indicates the counter should be incremented&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; signalPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;strong&gt;            &lt;/strong&gt;&lt;strong&gt;&lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Reset port&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; resetPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;&lt;/strong&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Query port - indicates that the counter should be read&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; queryPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Quit port - indicates that the interleave should exit&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt; quitPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Declare the interleave&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt; il = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt;(&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TeardownReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, quitPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Finished.&quot;&lt;/span&gt;);&lt;br /&gt;                    done.Set();&lt;br /&gt;                })),&lt;br /&gt;&lt;strong&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ExclusiveReceiverGroup&lt;/span&gt;(&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, signalPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                        ++counter;&lt;br /&gt;                    }),&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, resetPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                        counter = 0;&lt;br /&gt;                    })),&lt;br /&gt;&lt;/strong&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ConcurrentReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, queryPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(counter.ToString());&lt;br /&gt;                })));&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Then activate it&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(dq, il);&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Now start a timer that will fire every second, then read the console. An empty&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// line causes the program to quit.&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Timer&lt;/span&gt; t = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Timer&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; { signalPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance); })) {&lt;br /&gt;                t.Change(0, 1000);&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; line = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;while&lt;/span&gt; (line.Length &amp;gt; 0) {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;if&lt;/span&gt; (line == &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;q&quot;&lt;/span&gt;)&lt;br /&gt;                        queryPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;&lt;strong&gt;                    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;if&lt;/span&gt; (line == &lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;r&quot;&lt;/span&gt;)&lt;br /&gt;                        resetPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;&lt;/strong&gt;                    line = &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;                }&lt;br /&gt;                quitPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;EmptyValue&lt;/span&gt;.SharedInstance);&lt;br /&gt;            }&lt;br /&gt;            done.WaitOne();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;p&gt;Note, that I could have combined two Interleaves to the same effect. The following snippet illustrates how I might have done that:&lt;/p&gt;&lt;pre class=&quot;code&quot;&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Declare the interleave&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt; il = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt;(&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TeardownReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, quitPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Finished.&quot;&lt;/span&gt;);&lt;br /&gt;                    done.Set();&lt;br /&gt;                })),&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ExclusiveReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, signalPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    ++counter;&lt;br /&gt;                })),&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ConcurrentReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, queryPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(counter.ToString());&lt;br /&gt;                })));&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Declare the second interleave&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt; il2 = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Interleave&lt;/span&gt;(&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;TeardownReceiverGroup&lt;/span&gt;(),&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ExclusiveReceiverGroup&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Receive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;true&lt;/span&gt;, resetPort, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt; {&lt;br /&gt;                    counter = 0;&lt;br /&gt;                })),&lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;ConcurrentReceiverGroup&lt;/span&gt;());&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Combine them&lt;br /&gt;&lt;/span&gt;            il.CombineWith(il2);&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,0)&quot;&gt;// Then activate it&lt;br /&gt;&lt;/span&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(dq, il);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;In my next post, I&#39;ll cover Dispatchers, custom thread-pools and COM apartment interoperability.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/9199268870638599692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/9199268870638599692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/9199268870638599692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/9199268870638599692'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/07/ccr-101-part-7-interleave.html' title='CCR 101 - Part 7: Interleave'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-1235256794451575461</id><published>2007-07-26T23:47:00.001+10:00</published><updated>2007-07-27T00:04:20.753+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CCR"/><category scheme="http://www.blogger.com/atom/ns#" term="Programming"/><title type='text'>CCR 101 - Part 6: Arbitrations (Join)</title><content type='html'>&lt;p&gt;Actually, we&#39;ve covered Joins already. I just forgot to mention it. The MultipleItemReceives we covered in &lt;a href=&quot;http://iodyne.blogspot.com/2007/07/ccr-101-part-4-arbitrations-receivers.html&quot;&gt;Part 4&lt;/a&gt; are joins, i.e. they wait for all the ports to produce &lt;em&gt;n &lt;/em&gt;messages.&amp;nbsp;All Joins (like their name suggests) are just rendezvous points for a set of messages and are an important construct -&amp;nbsp;without them, we wouldn&#39;t easily be able to gather the results of a parallelized operation.&lt;/p&gt; &lt;p&gt;Whilst the most useful arbiters are typically those that allow you to deal with a concurrency problem whose size isn&#39;t known until runtime, there exists a join across two ports that is explicitly provided for by the Arbiter class (not unlike Choice in fact). The following sample takes a number, &lt;em&gt;n&lt;/em&gt;, and a string from the console and prints that string &lt;em&gt;n&lt;/em&gt; times.&lt;/p&gt;&lt;a href=&quot;http://11011.net/software/vspaste&quot;&gt;&lt;/a&gt;&lt;pre class=&quot;code&quot;&gt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Sample0601&lt;/span&gt; {&lt;br /&gt;    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;void&lt;/span&gt; Main(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;[] args) {&lt;br /&gt;        &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;using&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt; dq = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;DispatcherQueue&lt;/span&gt;()) {&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt;&amp;gt; intPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;&amp;gt; stringPort = &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Port&lt;/span&gt;&amp;lt;&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt;&amp;gt;();&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.Activate(dq, &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Arbiter&lt;/span&gt;.JoinedReceive(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;false&lt;/span&gt;, intPort, stringPort, &lt;br /&gt;                &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;delegate&lt;/span&gt;(&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; n, &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;string&lt;/span&gt; s) {&lt;br /&gt;                    &lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;for&lt;/span&gt; (&lt;span style=&quot;color: rgb(0,0,255)&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; n; ++i) {&lt;br /&gt;                        &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.WriteLine(s);&lt;br /&gt;                    }&lt;br /&gt;                }));&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.Write(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Enter a number: &quot;&lt;/span&gt;);&lt;br /&gt;            intPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Int32&lt;/span&gt;.Parse(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine()));&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.Write(&lt;span style=&quot;color: rgb(128,0,0)&quot;&gt;&quot;Enter a phrase: &quot;&lt;/span&gt;);&lt;br /&gt;            stringPort.Post(&lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine());&lt;br /&gt;            &lt;span style=&quot;color: rgb(0,128,128)&quot;&gt;Console&lt;/span&gt;.ReadLine();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;In the next post, I&#39;ll introduce the final arbitration, &lt;em&gt;Interleave&lt;/em&gt;. Conceptually, its a message-passing version of the Reader-Writer lock, scheduling readers and writers in a way that balances concurrency with correctness, albeit in an asynchronous fashion. Nearly every resource with some modifiable state can be protected by an Interleave and indeed it forms a core component of every service in the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb483067.aspx&quot;&gt;DSS&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Once the section on Arbitrations is complete, I want to cover the following (in order).&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Dispatchers. So far we&#39;ve only really&amp;nbsp;looked at&amp;nbsp;DispatcherQueues running across the CLR thread-pool. By using our own Dispatchers we can control the number of threads and various properties of those threads (such as COM Apartment type).&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Iterative Tasks. Hugely important to the CCR, IterativeTasks exploit C# 2.0&amp;nbsp;iterator functionality to&amp;nbsp;allow logical sequences of asynchronous methods to be written without ever blocking a physical thread.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Causalities. A cross-thread extension of exceptions, they allow errors raised in some scheduled task, to propagate through their causalities, back to the instigator of the operation.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;Longer term, I&#39;ll be posting some useful samples of code, illustrating usage with asynchronous sockets,&amp;nbsp;asynchronous database interaction,&amp;nbsp;interoperability with COM and UI threads and how the CCR can power your WCF-enabled server (or async ASP.NET web pages). If you have any specific requests, please leave them in the comments section.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/1235256794451575461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/1235256794451575461' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/1235256794451575461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/1235256794451575461'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/07/ccr-101-part-6-arbitrations-join.html' title='CCR 101 - Part 6: Arbitrations (Join)'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-39413407965920307.post-7390793686013989368</id><published>2007-07-26T22:34:00.001+10:00</published><updated>2007-07-27T00:04:45.940+10:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Buffoonery"/><title type='text'>Web Buffoon</title><content type='html'>&lt;p&gt;I notice that this blog doesn&#39;t render properly on IE6. I have figured out a fix of sorts (something to do with the text in a fixed-length DIV overflowing) with some &lt;a href=&quot;http://www.positioniseverything.net/explorer/expandingboxbug.html&quot;&gt;help&lt;/a&gt;,&amp;nbsp;but need to make sure it doesn&#39;t break the experience for IE7 and Firefox users, before I apply it. As my CSS skills fall somewhere short of useless, this may take a couple of days.&lt;/p&gt; &lt;p&gt;I&#39;ve also noticed that the code is considerably less legible on Firefox than on IE. I&#39;ll try and fix that too. Thank you for your patience.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://iodyne.blogspot.com/feeds/7390793686013989368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/39413407965920307/7390793686013989368' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/7390793686013989368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/39413407965920307/posts/default/7390793686013989368'/><link rel='alternate' type='text/html' href='http://iodyne.blogspot.com/2007/07/web-buffoon.html' title='Web Buffoon'/><author><name>NickG</name><uri>http://www.blogger.com/profile/03496738652157699894</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>