<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.microsoft.co.il/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Bnaya Eshet</title><subtitle type="html" /><id>http://blogs.microsoft.co.il/blogs/bnaya/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/" /><link rel="self" type="application/atom+xml" href="http://blogs.microsoft.co.il/blogs/bnaya/atom.aspx" /><generator uri="http://communityserver.org" version="3.1.20917.1142">Community Server</generator><updated>2011-12-18T20:29:00Z</updated><entry><title>Rx - DistinctUntilChanged</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/02/02/rx-distinctuntilchanged.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/02/02/rx-distinctuntilchanged.aspx</id><published>2012-02-02T19:27:19Z</published><updated>2012-02-02T19:27:19Z</updated><content type="html">&lt;p&gt;Rx - DistinctUntilChanged&lt;/p&gt;  &lt;p&gt;this post will focus on the &lt;strong&gt;simple yet very useful DistinctUntilChanged&lt;/strong&gt; operator.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_9787_2204_59B52305.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, IObservable, IObserver, Buffer, Parallel, Concurrency, DistinctUntilChanged" border="0" alt="Rx, IObservable, IObserver, Buffer, Parallel, Concurrency, DistinctUntilChanged" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_9787_2204_thumb_47E4A106.png" width="491" height="323" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;sometimes a datum stream may produce the same value for a while, you can see it in stock exchange stream the value of specific stock may be steady for a while.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;observer&lt;/strong&gt; can &lt;strong&gt;reduce its computation level&lt;/strong&gt; by ignoring a repeatable value (sequential repeatable value, for none sequential you can use the &lt;strong&gt;Distinct&lt;/strong&gt; operator).&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;DistinctUntilChanged&lt;/strong&gt; is having the following overloads:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:df50456d-d0e3-4025-a9a2-afc3ba5c5c29" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource&amp;gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource, TKey&amp;gt;(&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TSource, TKey&amp;gt; keySelector);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource&amp;gt;(&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;IEqualityComparer&lt;/span&gt;&amp;lt;TSource&amp;gt; comparer);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; DistinctUntilChanged&amp;lt;TSource, TKey&amp;gt;(&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TSource, TKey&amp;gt; keySelector, &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;IEqualityComparer&lt;/span&gt;&amp;lt;TKey&amp;gt; comparer);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;I was hiding the fist parameter of the extension method which is: &lt;em&gt;&lt;strong&gt;this IObservable&amp;lt;TSource&amp;gt; source&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;you can use the &lt;strong&gt;first overload&lt;/strong&gt; when you dealing with a &lt;strong&gt;simple datum stream&lt;/strong&gt; (of primitive or simple value type),     &lt;br /&gt;but &lt;strong&gt;real-life datum stream&lt;/strong&gt; are often &lt;strong&gt;more complex&lt;/strong&gt;.     &lt;br /&gt;for complex scenario you may prefer one of the other 3 overloads where you can define the comparison.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;stock exchange&lt;/strong&gt; scenario may be looking something like the following snippet:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:60021c30-f128-4515-a72a-71f74886a3c0" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Stock&lt;/span&gt;&amp;gt; AlertStream(&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Stock&lt;/span&gt;&amp;gt; provider)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; oldAndCurrent &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; provider&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;               .DistinctUntilChanged(stock =&amp;gt; stock.Price)&lt;/li&gt; &lt;li&gt;               .Buffer(2,1)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;           &lt;span style="color:#0000ff;"&gt;let&lt;/span&gt; old = oldAndCurrent[0]&lt;/li&gt; &lt;li&gt;           &lt;span style="color:#0000ff;"&gt;let&lt;/span&gt; current = oldAndCurrent[1]&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;           &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; old.Price &amp;lt; current.Price &amp;amp;&amp;amp;&lt;/li&gt; &lt;li&gt;                 old.Volume + FACTOR &amp;lt; current.Volume &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;           &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; current;&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the sample is using a sliding &lt;strong&gt;buffer of 2&lt;/strong&gt;,     &lt;br /&gt;you can read more about the &lt;strong&gt;Buffer&lt;/strong&gt; operator in &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/22/rx-buffer.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;the AlertStream method is getting a stock stream.&lt;/p&gt;  &lt;p&gt;it &lt;strong&gt;filter steady price out&lt;/strong&gt; by using the &lt;strong&gt;DistinctUntilChanged &lt;/strong&gt;operator with a &lt;strong&gt;lambda&lt;/strong&gt; that indicate the &lt;strong&gt;Price property&lt;/strong&gt; as the &lt;strong&gt;comparison&lt;/strong&gt; property.&lt;/p&gt;  &lt;p&gt;after that it &lt;strong&gt;buffer&lt;/strong&gt; the &lt;strong&gt;current&lt;/strong&gt; value with the &lt;strong&gt;previous&lt;/strong&gt; value (without the distinct the buffer will not ignore steady couples) .&lt;/p&gt;  &lt;p&gt;last thing the snippet is doing before it returns a filtered stream is to filter out old / current couples that does not match a criteria.&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;as simple as the &lt;strong&gt;DistinctUntilChanged&lt;/strong&gt; is, it is one of useful operator which you should not ignore.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Rx-DistinctUntilChanged-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F02%2F02%2Frx-distinctuntilchanged.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1005162" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /><category term="Buffer" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Buffer/default.aspx" /><category term="DistinctUntilChanged" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DistinctUntilChanged/default.aspx" /><category term="Concurrency" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Concurrency/default.aspx" /></entry><entry><title>Tpl Dataflow walkthrough - Part 5</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/28/tpl-dataflow-walkthrough-part-5.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/28/tpl-dataflow-walkthrough-part-5.aspx</id><published>2012-01-28T10:04:31Z</published><updated>2012-01-28T10:04:31Z</updated><content type="html">&lt;h2&gt;Tpl Dataflow walkthrough - Part 5&lt;/h2&gt;  &lt;p&gt;this post is a &lt;strong&gt;complete walkthrough&lt;/strong&gt; of a &lt;strong&gt;web crawler&lt;/strong&gt; sample that was build purely by using &lt;strong&gt;Tpl Dataflow&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;it was built on &lt;strong&gt;.NET 4.5 / C# 5&lt;/strong&gt; (on a virtual machine using &lt;strong&gt;VS 11&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;I will analyze each part of this sample, both by discussing the &lt;strong&gt;Dataflow&lt;/strong&gt; blocks and the &lt;strong&gt;patterns&lt;/strong&gt; in used.&lt;/p&gt;  &lt;p&gt;the sample code is available in &lt;a href="https://skydrive.live.com/redir.aspx?cid=9bf7c1a515d76a9a&amp;amp;resid=9BF7C1A515D76A9A!1404&amp;amp;parid=9BF7C1A515D76A9A!1321&amp;amp;authkey=!ACW2DtTH6k5CuTk" target="_blank"&gt;here&lt;/a&gt; (it is a VS 11 project).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_6257_60FC8823.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_6257_thumb_5309F68E.png" width="405" height="307" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;during the walkthrough you will see the following &lt;strong&gt;Tpl Dataflow &lt;/strong&gt;blocks:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;TransformBlock &lt;/li&gt;    &lt;li&gt;TransformManyBlock &lt;/li&gt;    &lt;li&gt;ActionBlock &lt;/li&gt;    &lt;li&gt;BroadcastBlock &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;you will see how the &lt;strong&gt;aysnc / await&lt;/strong&gt; &lt;strong&gt;signature&lt;/strong&gt; of the &lt;strong&gt;Dataflow&lt;/strong&gt; &lt;strong&gt;blocks&lt;/strong&gt; is better for executing an&lt;strong&gt; IO bound operation&lt;/strong&gt; (without freezing a worker ThreadPool thread).&lt;/p&gt;  &lt;p&gt;I should also mention that this post is part of the &lt;strong&gt;Tpl Dataflow &lt;/strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TDF/default.aspx" target="_blank"&gt;series&lt;/a&gt; which you better read before reading this one.&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;Disclamation: the web crawler sample is for educational purpose only (running web crawler application may be forbidden by the low of your country).&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;The sample topography:&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;Tpl Dataflow&lt;/strong&gt; application is usually a collection of &lt;strong&gt;agents&lt;/strong&gt; which is linked together in order to compose a complete solution. &lt;strong&gt;each agent is having its own responsibilities and concerns&lt;/strong&gt;. the following diagram present the agent topography for this sample:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_7521B67A.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_27E19722.png" width="520" height="405" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;h5&gt;agents block type and responsibilities&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;Downloader&lt;/strong&gt;: the responsibility of the downloader is to download the html of a web page. it is using a &lt;strong&gt;TransformBlock&amp;lt;Tin, Tout&amp;gt; &lt;/strong&gt;which belong to the executer block family. the transform block is getting a url as the input message and it produce the page&amp;#39;s html as it output.&lt;/p&gt;  &lt;p&gt;the transform block is construct from:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;input buffer (for url) &lt;/li&gt;    &lt;li&gt;task (do the transformation) &lt;/li&gt;    &lt;li&gt;output buffer (for the downloaded html) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;the &lt;strong&gt;task&lt;/strong&gt; is taking one message at a time from the input buffer, transform the message by a&lt;strong&gt; Func&amp;lt;Tin, Tout&amp;gt;&lt;/strong&gt; delegate which it get as a constructor parameter and put the result in the output buffer, where it is available for other blocks to consume.&lt;/p&gt;  &lt;p&gt;later we will see that our crawler transformation is actually taking &lt;strong&gt;Func&amp;lt;Tin, Task&amp;lt;Tout&amp;gt;&amp;gt; &lt;/strong&gt;which is a better signature for &lt;strong&gt;IO bound&lt;/strong&gt; operations (I will discuss it latter).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_5B79DDB3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_51D16F7D.png" width="400" height="120" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the transform block is a propagator block which mean that it exposed both as a target and a source block. it is implementing &lt;strong&gt;IPropagatorBlock&amp;lt;Tin, Tout&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the following snippet show that &lt;strong&gt;IPropagatorBlock&lt;/strong&gt; is simply an encapsulation of &lt;strong&gt;ITargetBlock&lt;/strong&gt; and &lt;strong&gt;ISourceBlock&lt;/strong&gt;.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:422eacdf-bea3-4f32-8922-a99ef267161e" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IPropagatorBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; TInput, &lt;span style="color:#0000ff;"&gt;out&lt;/span&gt; TOutput&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    : ITargetBlock&amp;lt;TInput&amp;gt;, &lt;/li&gt; &lt;li&gt;      ISourceBlock&amp;lt;TOutput&amp;gt;, &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;      IDataflowBlock&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;Start crawling&lt;/h5&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b05be473-d938-4ab3-995b-326a15e7dd7d" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; downloader = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TransformBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; (url) =&amp;gt;&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#008000;"&gt;// using IOCP the thread pool worker thread does return to the pool&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;WebClient&lt;/span&gt; wc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;WebClient&lt;/span&gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; result = &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; wc.DownloadStringTaskAsync(url);&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; result;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }, downloaderOptions);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;as I was mentioning earlier the downloader contractor is getting &lt;strong&gt;Func&amp;lt;Tin, Task&amp;lt;Tout&amp;gt;&amp;gt;&lt;/strong&gt;, therefore we can apply an async lambda expression (line 2). the code &lt;strong&gt;await&lt;/strong&gt; for downloading (at line 6). &lt;/p&gt;  &lt;p&gt;if you are not familiar with the &lt;strong&gt;async / await&lt;/strong&gt; concept you can read &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/29/the-concept-of-async-await.aspx" target="_blank"&gt;this&lt;/a&gt; post or more posts in &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/await/default.aspx" target="_blank"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;anyway &lt;strong&gt;while&lt;/strong&gt; &lt;strong&gt;awaiting&lt;/strong&gt; for the download (DownloadStringTaskAsync) the &lt;strong&gt;block&amp;#39;s task&lt;/strong&gt; is actually &lt;strong&gt;return its worker thread&lt;/strong&gt; to the ThreadPool and take advantage of the &lt;a href="http://en.wikipedia.org/wiki/Input/output_completion_port" target="_blank"&gt;IOCP&lt;/a&gt; (IO Completion Port), &lt;font color="#666666"&gt;this is an IO bound operation which mean that no CPU resources is needed &lt;/font&gt;&lt;font color="#666666"&gt;while the network card fetching the data from the network&lt;/font&gt;.     &lt;br /&gt;it is important to understand that while the network card is handling the request the &lt;strong&gt;agent&amp;#39;s task does not fetching another message from the buffer&lt;/strong&gt;, the task will be interrupt when the data will be available. &lt;/p&gt;  &lt;h5&gt;analyzing the html &lt;/h5&gt;  &lt;p&gt;the crawler is using 2 agent for analyze the downloaded html:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;link parser&lt;/strong&gt; (which will look for links elements &amp;lt;a href=&amp;quot;...&amp;quot;/&amp;gt;) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;image parser&lt;/strong&gt; (which will look for image elements &amp;lt;image src=&amp;quot;...&amp;quot;/&amp;gt;) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;both agent should be link to the downloader agent.    &lt;br /&gt;the problem is that &lt;strong&gt;linking both agent directly&lt;/strong&gt; to the downloader agent &lt;strong&gt;will result with starvation&lt;/strong&gt; of one of the agent.     &lt;br /&gt;unlike &lt;strong&gt;Rx&lt;/strong&gt; the most blocks forward messages into the first linked target that accept the message, and ignore other linked targets. which mean that the message will be handle by a single agent at a time.&lt;/p&gt;  &lt;p&gt;broadcast behavior can be achieved by using a &lt;strong&gt;BroadcastBlock&amp;lt;T&amp;gt;&lt;/strong&gt; which is part of the pure buffer family.     &lt;br /&gt;the broadcast block is construct from:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;input buffer &lt;/li&gt;    &lt;li&gt;task &lt;/li&gt;    &lt;li&gt;output buffer of single item. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_6A8096C0.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_4BE6A617.png" width="421" height="125" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the task is fetching a message from the input buffer and place it in the output buffer, from the output buffer the message submit to the linked block.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;broadcast block&lt;/strong&gt; is getting a &lt;strong&gt;Func&amp;lt;T,T&amp;gt; delegate &lt;/strong&gt;as a constructor parameter, the idea behind it is &lt;strong&gt;cloning&lt;/strong&gt; (which will enable separation of the messages).     &lt;br /&gt;if you are passing a &lt;strong&gt;reference type message&lt;/strong&gt; to &lt;strong&gt;multiple agents&lt;/strong&gt;, without cloning, changes that made by one agent will be visible to all the other agents.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;broadcast block&lt;/strong&gt; will use the &lt;strong&gt;cloning delegate&lt;/strong&gt; &lt;strong&gt;before sending&lt;/strong&gt; the message to the linked agents.     &lt;br /&gt;the cloning pattern will ensure that only single block is processing a message instance at a time, this will maintain the &lt;strong&gt;message ownership&lt;/strong&gt; and avoid the needs of data synchronization for &lt;strong&gt;thread safety&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the crawler will use the following block definition for broadcasting:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5e9c8188-1ebd-422c-ad5d-b139b99fb104" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; contentBroadcaster = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BroadcastBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(s =&amp;gt; s);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;in our case the html content is a string which is immutable, therefore no real cloning is needed.&lt;/p&gt;  &lt;p&gt;the crawler will link the agents (blocks) to each other after the construction of all the relevant blocks, right now we are focusing on the agents themselves.&lt;/p&gt;  &lt;h5&gt;Link parser&lt;/h5&gt;  &lt;p&gt;the link parser is using the following regular expression in order to fetch all the links (&amp;lt;a href=...&amp;quot;/&amp;gt;) out from the html and extract the link&amp;#39;s url.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6eaa187b-912d-43d1-be12-7baf5275aa9b" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; LINK_REGEX_HREF = &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;#92;&amp;#92;shref=(&amp;#39;|&amp;#92;&amp;#92;&amp;#92;&amp;quot;)?(?&amp;lt;LINK&amp;gt;http&amp;#92;&amp;#92;://.*?(?=&amp;#92;&amp;#92;1)).*&amp;gt;&amp;quot;&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Regex&lt;/span&gt; _linkRegexHRef = &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Regex&lt;/span&gt;(LINK_REGEX_HREF);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;unlike the downloader agent which get a single input (url) and &lt;strong&gt;produce a single output &lt;/strong&gt;(html),     &lt;br /&gt;the &lt;strong&gt;link parser produce multiple outputs&lt;/strong&gt; (links) per each input (html).     &lt;br /&gt;you can use the transform block and set the output type to array of links but the &lt;strong&gt;Tpl Dataflow&lt;/strong&gt; is having a better block for this scenario.     &lt;br /&gt;because the processing of each link is independent of other links, it will be better if the transform output buffer will contain flatten links objects rather then a collection of link&amp;#39;s array.&lt;/p&gt;  &lt;p&gt;the crawler is using the &lt;strong&gt;TransformManyBlock&amp;lt;Tin,Tout&amp;gt;&lt;/strong&gt;. this block is similar to the &lt;strong&gt;transform block&lt;/strong&gt; with only one difference, the delegate at the constructor parameter is one of the following delegates:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Func&amp;lt;Tin, IEnumerable&amp;lt;Tout&amp;gt;&amp;gt;&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Func&amp;lt;Tin, Task&amp;lt;IEnumerable&amp;lt;Tout&amp;gt;&amp;gt;&amp;gt;&lt;/strong&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;the block task will extract the outputs results and put each of the extracted result, separately, in the output buffer.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_2F893E2A.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_05C5C337.png" width="499" height="121" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;this is the code for the link parser agent:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e4c3ea87-8947-43a6-8b1a-76d3ab8c8455" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; linkParser = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TransformManyBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;       (html) =&amp;gt;&lt;/li&gt; &lt;li&gt;       {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;           &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; output = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/li&gt; &lt;li&gt;           &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; links = _linkRegexHRef.Matches(html);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;           &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Match&lt;/span&gt; item &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; links)&lt;/li&gt; &lt;li&gt;           {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;               &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; value = item.Groups[&lt;span style="color:#a31515;"&gt;&amp;quot;LINK&amp;quot;&lt;/span&gt;].Value;&lt;/li&gt; &lt;li&gt;               output.Add(value);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;           }&lt;/li&gt; &lt;li&gt;           &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; output;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;       });&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;it is very straight forward, parse each html by using regex and return list of result which the block will extract into the output buffer.&lt;/p&gt;  &lt;h5&gt;Image parser&lt;/h5&gt;  &lt;p&gt;the image parser is quit similar to the link parser.    &lt;br /&gt;the only differences is that it using different regular expression which extract the image&amp;#39;s url.&lt;/p&gt;  &lt;p&gt;the regex part is:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b7393f8c-5e66-4da2-bf4c-3f18ff447c2b" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; IMG_REGEX =&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;&amp;#92;&amp;#92;s*img [^&amp;#92;&amp;#92;&amp;gt;]*src=(&amp;#39;|&amp;#92;&amp;quot;)?(?&amp;lt;IMG&amp;gt;http&amp;#92;&amp;#92;://.*?(?=&amp;#92;&amp;#92;1)).*&amp;gt;&amp;#92;&amp;#92;s*([^&amp;lt;]+|.*?)?&amp;#92;&amp;#92;s*&amp;lt;/a&amp;gt;&amp;quot;&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Regex&lt;/span&gt; _imgRegex =&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Regex&lt;/span&gt;(IMG_REGEX);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;and the parser agent code is:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6add4233-6be0-4155-b5f2-2a452e5d6204" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; imgParser = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TransformManyBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        (html) =&amp;gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; output = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; images = _imgRegex.Matches(html);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Match&lt;/span&gt; item &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; images)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; value = item.Groups[&lt;span style="color:#a31515;"&gt;&amp;quot;IMG&amp;quot;&lt;/span&gt;].Value;&lt;/li&gt; &lt;li&gt;                output.Add(value);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; output;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        });&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;writer agent&lt;/h5&gt;  &lt;p&gt;the last operational agent is the writer agent which will download the an image from a url and save it to the local disk.&lt;/p&gt;  &lt;p&gt;the writer is using a simple &lt;strong&gt;action block&lt;/strong&gt;, which is a simple executer block that have an input buffer and a task.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_494D4E8C.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_1B1352D2.png" width="202" height="109" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the task is fetching messages from the buffer and execute a delegate which is given as constructor parameter.    &lt;br /&gt;the delegate signature can be either &lt;strong&gt;Action&amp;lt;T&amp;gt;&lt;/strong&gt; or &lt;strong&gt;Funk&amp;lt;T, Task&amp;gt;&lt;/strong&gt;. the latter one is great for &lt;strong&gt;IO bound operation&lt;/strong&gt; (from the same reasons discussed earlier when we was looking on the transform block signature).&lt;/p&gt;  &lt;p&gt;because the writer is doing 2 IO bound operations:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;download the image from the web &lt;/li&gt;    &lt;li&gt;write the image to the file system &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;the crawler is using the &lt;strong&gt;Funk&amp;lt;T, Task&amp;gt;&lt;/strong&gt; signature.     &lt;br /&gt;the writer code is:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c4c18393-327f-4ebb-b35a-2dfe2d982f02" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; writer = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ActionBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(&lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; url =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;WebClient&lt;/span&gt; wc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;WebClient&lt;/span&gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// using IOCP the thread pool worker thread does return to the pool&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;byte&lt;/span&gt;[] buffer = &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; wc.DownloadDataTaskAsync(url);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; fileName = &lt;span style="color:#2b91af;"&gt;Path&lt;/span&gt;.GetFileName(url);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name = &lt;span style="color:#a31515;"&gt;@&amp;quot;Images&amp;#92;&amp;quot;&lt;/span&gt; + fileName;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Stream&lt;/span&gt; srm = &lt;span style="color:#2b91af;"&gt;File&lt;/span&gt;.OpenWrite(name))&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; srm.WriteAsync(buffer, 0, buffer.Length);&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;});&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the first &lt;strong&gt;await&lt;/strong&gt; at line 5, is awaiting until the task will be &lt;strong&gt;interrupt by the network card&lt;/strong&gt;,     &lt;br /&gt;and the second &lt;strong&gt;await&lt;/strong&gt; at line 12, will await until it will be &lt;strong&gt;interrupt by the file system controller&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;you may have been notice that the second &lt;strong&gt;await&lt;/strong&gt; is within a &lt;strong&gt;using block&lt;/strong&gt;, you can read more about this topic at &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/15/using-async-await.aspx" target="_blank"&gt;this&lt;/a&gt; post.&lt;/p&gt;  &lt;h5&gt;link it together&lt;/h5&gt;  &lt;p&gt;right now we are having most of our building blocks and it is time to define the data-flow by linking the block to each other.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;downloader&lt;/strong&gt; should be link to the &lt;strong&gt;content broadcaster&lt;/strong&gt; which in tern should be linked both to the &lt;strong&gt;image and link parser&lt;/strong&gt;, the image parser should be linked to the &lt;strong&gt;writer&lt;/strong&gt; and the &lt;strong&gt;link parser&lt;/strong&gt; should be &lt;strong&gt;linked back to the downloader&lt;/strong&gt; (so it can crawl farther).&lt;/p&gt;  &lt;p&gt;but there is one last issue.    &lt;br /&gt;it happens that some web page is having links that is targeting an image. this lead us to more complex linking where the link parser should be linked both to the downloader and having conditional link to the writer for those url that is having an image suffix.     &lt;br /&gt;as we discuss earlier having a direct link from the link parser to both the downloader and the writer will results with starvation of one of those agents.     &lt;br /&gt;we do need a final broadcast block which will handle this distribution task. &lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dc3b0644-3e5c-4a37-ba0c-1f8cc81b2cdb" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; linkBroadcaster = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BroadcastBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(s =&amp;gt; s);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the &lt;strong&gt;link parser&lt;/strong&gt; will be linked to the &lt;strong&gt;broadcaster&lt;/strong&gt; and the broadcaster will be liked to both the &lt;strong&gt;downloader&lt;/strong&gt; and the &lt;strong&gt;writer&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;we have spoke of the conditional link from the link parser and the writer, but it will be more effective if the link parser to the downloader will be link only those pages that are most likely having useful data like php, aspx, htm, ext...&lt;/p&gt;  &lt;h5&gt;Filtering linked messages&lt;/h5&gt;  &lt;p&gt;the following predicates will be use in order to filter linked messages:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0ecb60ad-f394-49fc-b8fb-7505f9c7e164" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;StringComparison&lt;/span&gt; comparison = &lt;span style="color:#2b91af;"&gt;StringComparison&lt;/span&gt;.InvariantCultureIgnoreCase;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Predicate&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; linkFilter = link =&amp;gt; &lt;/li&gt; &lt;li&gt;    link.IndexOf(&lt;span style="color:#a31515;"&gt;&amp;quot;.aspx&amp;quot;&lt;/span&gt;, comparison) != -1 ||&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    link.IndexOf(&lt;span style="color:#a31515;"&gt;&amp;quot;.php&amp;quot;&lt;/span&gt;, comparison) != -1 ||&lt;/li&gt; &lt;li&gt;    link.IndexOf(&lt;span style="color:#a31515;"&gt;&amp;quot;.htm&amp;quot;&lt;/span&gt;, comparison) != -1 ||&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    link.IndexOf(&lt;span style="color:#a31515;"&gt;&amp;quot;.html&amp;quot;&lt;/span&gt;, comparison) != -1;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Predicate&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; imgFilter = url =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    url.EndsWith(&lt;span style="color:#a31515;"&gt;&amp;quot;.jpg&amp;quot;&lt;/span&gt;, comparison) ||&lt;/li&gt; &lt;li&gt;    url.EndsWith(&lt;span style="color:#a31515;"&gt;&amp;quot;.png&amp;quot;&lt;/span&gt;, comparison) ||&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    url.EndsWith(&lt;span style="color:#a31515;"&gt;&amp;quot;.gif&amp;quot;&lt;/span&gt;, comparison);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the first predicate (line 2) will filter the downloader agent target and the second (line 7) will filter the link parser result which is targeting the writer agent.&lt;/p&gt;  &lt;h5&gt;compose the data-flow&lt;/h5&gt;  &lt;p&gt;finally we got to the agent composition.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_1C283BF1.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" border="0" alt="TDF, Tpl,Dataflow, ITargerBlock, ISorceBlock, IDataBlobk, Transform, IPropagatorBlock" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_4ADDCEC6.png" width="520" height="407" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:48166a5f-a656-4f62-a6d9-8881c898564e" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt; disposeAll = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;CompositeDisposable&lt;/span&gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// from [downloader] to [contentBroadcaster]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    downloader.LinkTo(contentBroadcaster),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// from [contentBroadcaster] to [imgParser]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    contentBroadcaster.LinkTo(imgParser),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// from [contentBroadcaster] to [linkParserHRef]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    contentBroadcaster.LinkTo(linkParser),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// from [linkParser] to [linkBroadcaster]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    linkParser.LinkTo(linkBroadcaster),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// conditional link to from [linkBroadcaster] to [downloader]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    linkBroadcaster.LinkTo(downloader, linkFilter, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// from [linkBroadcaster] to [writer]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    linkBroadcaster.LinkTo(writer, imgFilter, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#008000;"&gt;// from [imgParser] to [writer]&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    imgParser.LinkTo(writer));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;each &lt;strong&gt;LinkTo&lt;/strong&gt; operation return a &lt;strong&gt;disposable&lt;/strong&gt; instance which can be use to&lt;strong&gt; dispose the link&lt;/strong&gt; when it no longer needed. the crawler &lt;strong&gt;compose all those disposable&lt;/strong&gt; together into a single disposable called &lt;strong&gt;dispose All&lt;/strong&gt; by using the &lt;strong&gt;CompositeDisposable&lt;/strong&gt; which is part of the &lt;strong&gt;Rx&lt;/strong&gt; library.&lt;/p&gt;  &lt;p&gt;you can see the conditional LinkTo at line 11 and 13.    &lt;br /&gt;is is &lt;strong&gt;very important&lt;/strong&gt; to set the last parameter of the &lt;strong&gt;LinkTo&lt;/strong&gt; to true if you don&amp;#39;t want to dispose the link when the filter doesn&amp;#39;t match the criteria.&lt;/p&gt;  &lt;h5&gt;summary&lt;/h5&gt;  &lt;p&gt;this post was a walkthrough of a web crawler sample.    &lt;br /&gt;the complete sample, which is available in &lt;a href="https://skydrive.live.com/redir.aspx?cid=9bf7c1a515d76a9a&amp;amp;resid=9BF7C1A515D76A9A!1404&amp;amp;parid=9BF7C1A515D76A9A!1321&amp;amp;authkey=!ACW2DtTH6k5CuTk" target="_blank"&gt;here&lt;/a&gt; (VS 11), is also having exception handling, agent termination after x amount of seconds, prevention of processing the same url twice and more. for simplicity the code within this post was a simplified version.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Tpl-Dataflow-walkthrough-Part-5-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F01%2F28%2Ftpl-dataflow-walkthrough-part-5.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=1000032" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="Dataflow" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Dataflow/default.aspx" /><category term="TDF" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TDF/default.aspx" /><category term="IDataflowBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IDataflowBlock/default.aspx" /><category term="ISourceBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/ISourceBlock/default.aspx" /><category term="ITargetBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/ITargetBlock/default.aspx" /><category term="async" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/async/default.aspx" /><category term="await" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/await/default.aspx" /><category term="TPL Dataflow" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL+Dataflow/default.aspx" /><category term="TAP" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TAP/default.aspx" /><category term="C#5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/C_2300_5/default.aspx" /><category term="IDataBlobk" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IDataBlobk/default.aspx" /><category term="ISorceBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/ISorceBlock/default.aspx" /><category term="Transform" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Transform/default.aspx" /><category term="ITargerBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/ITargerBlock/default.aspx" /></entry><entry><title>Rx - Aggregate vs. Scan</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/24/rx-aggregate-vs-scan.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/24/rx-aggregate-vs-scan.aspx</id><published>2012-01-24T11:25:52Z</published><updated>2012-01-24T11:25:52Z</updated><content type="html">&lt;h2&gt;Rx - Aggregate vs. Scan&lt;/h2&gt;  &lt;p&gt;this post will focus on 2 &lt;strong&gt;Rx&lt;/strong&gt; operators &lt;strong&gt;Aggregate&lt;/strong&gt; and &lt;strong&gt;Scan&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_6783_7D4B337A.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, Reactive extension, aggregate, scan, Iobservable, IObserver" border="0" alt="Rx, Reactive extension, aggregate, scan, Iobservable, IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_6783_thumb_7E6F80BF.png" width="408" height="267" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;both &lt;strong&gt;Aggregate&lt;/strong&gt; and &lt;strong&gt;Scan&lt;/strong&gt; are dealing with &lt;strong&gt;event stream&lt;/strong&gt; &lt;strong&gt;accumulation&lt;/strong&gt;, the only difference is that &lt;strong&gt;Aggregate&lt;/strong&gt; produce &lt;strong&gt;single result&lt;/strong&gt; (upon the stream completion)     &lt;br /&gt;and &lt;strong&gt;Scan&lt;/strong&gt; present an ongoing runtime accumulation which &lt;strong&gt;react for each&lt;/strong&gt; &lt;strong&gt;OnNext&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;both operators has 2 overloads with the same signature:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d07dc14d-8452-41ff-9e19-a46a2e27a954" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; Aggregate&amp;lt;TSource&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; source, &lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TSource, TSource, TSource&amp;gt; accumulator);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; Scan&amp;lt;TSource&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; source, &lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TSource, TSource, TSource&amp;gt; accumulator);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TAccumulate&amp;gt; Aggregate&amp;lt;TSource, TAccumulate&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; source,&lt;/li&gt; &lt;li&gt;    TAccumulate seed, &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; accumulator);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TAccumulate&amp;gt; Scan&amp;lt;TSource, TAccumulate&amp;gt;(&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource&amp;gt; source, &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    TAccumulate seed,&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; accumulator);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the first overload (line 1,5) gets a simple accumulation Func&amp;lt;T,T,T&amp;gt; which get the previous accumulated value and the current value as parameters and should return new accumulated value (on &lt;font color="#666666"&gt;the first accumulation the previous accumulated value will be default(T)&lt;/font&gt;).&lt;/p&gt;  &lt;p&gt;the second overload define a seed value for the first accumulation and a Func&amp;lt;TAccumulate, TSource, TAccumulate&amp;gt; which get the previous accumulated value and the current value as parameters and should return new accumulated value.    &lt;br /&gt;notice that the accumulated value type can be different from the current value.&lt;/p&gt;  &lt;p&gt;for example the following stream:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:06d0c54b-1524-4522-bebb-4ccb780ebae9" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Range(1, 10);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; result = xs.Aggregate((acc, i) =&amp;gt; acc + i);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;result.ForEach(item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(item));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;will project a single result (55).&lt;/p&gt;  &lt;p&gt;while the Scan version:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:114575c2-364d-44d6-82a5-df5bb97d5b23" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Range(1, 10);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; result = xs.Scan((acc, i) =&amp;gt; acc + i);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;result.ForEach(item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(item));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;will project each accumulation interval:&lt;/p&gt;  &lt;p&gt;1    &lt;br /&gt;3     &lt;br /&gt;6     &lt;br /&gt;10     &lt;br /&gt;15     &lt;br /&gt;21     &lt;br /&gt;28     &lt;br /&gt;36     &lt;br /&gt;45     &lt;br /&gt;55&lt;/p&gt;  &lt;p&gt;both operator can become very handy within a Window operator.&lt;/p&gt;  &lt;p&gt;for more information about the Window operator see this &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/31/rx-window.aspx" target="_blank"&gt;post&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;for example, you may want to accumulate stream of customers which enter a store on per hour base.&lt;/p&gt;  &lt;p&gt;you can use the Window operator combine with the Aggregate operator to get per hour report    &lt;br /&gt;or using the Window combine with the Scan operation to get continues report per hour (&lt;font color="#666666"&gt;it will let you to react immediately for a live data, for example you can react when more then 100 customer were enter the store within un hour or less&lt;/font&gt;).&lt;/p&gt;  &lt;p&gt;the following code will demonstrate the aggregate scenario, but I should warn you, you are now stepping into some dark art code (which is the result of some concurrency behavior which I personally hope that the Rx team will address in the future in more intuitive way).&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;I consider to to add a few operator in future version of &lt;a href="http://rxcontrib.codeplex.com/" target="_blank"&gt;Rx Contrib&lt;/a&gt; which will handle this task more intuitively.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;and I will also post a work-through series of how to use the &lt;a href="http://rxcontrib.codeplex.com/" target="_blank"&gt;Rx Contrib&lt;/a&gt; libraries.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;what you will see is not the most intuitive code snippet but it is what you need in order to get the job done.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ba15472d-1005-4b60-bfb8-3798071f4258" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; storeStreamMock = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Generate&amp;lt;&lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;Unit&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt;(),   &lt;span style="color:#008000;"&gt;// random object&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    rnd =&amp;gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;,    &lt;span style="color:#008000;"&gt;// continue forever (exit term)&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    rnd =&amp;gt; rnd,     &lt;span style="color:#008000;"&gt;// next iteration value (ignored)&lt;/span&gt;&lt;/li&gt; &lt;li&gt;    rnd =&amp;gt; &lt;span style="color:#2b91af;"&gt;Unit&lt;/span&gt;.Default, &lt;span style="color:#008000;"&gt;// projection (allways project Unit.Default)&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    rnd =&amp;gt; &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(rnd.Next(10, 100))); &lt;span style="color:#008000;"&gt;// deley between iterations&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt; accStream =&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; win &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; storeStreamMock.Window(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; win.Aggregate(0, (acc, cur) =&amp;gt; acc + 1).ToTask();&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;accStream&lt;/li&gt; &lt;li&gt;    .ObserveOn(&lt;span style="color:#2b91af;"&gt;Scheduler&lt;/span&gt;.TaskPool)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    .ForEach(item =&amp;gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(item.Result));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;line 1-6 are generating a mock of store observable by using the Generate factory, you can completely ignore this part.&lt;/p&gt;  &lt;p&gt;at line 9 we define a window of 5 second.&lt;/p&gt;  &lt;p&gt;line 10 define the aggregation and export the aggregated value into a Task (TPL).&lt;/p&gt;  &lt;p&gt;it is part of the dark art, otherwise we will end up with blocking and contentions.&lt;/p&gt;  &lt;p&gt;the last part of the dark art is that you should process the result within the subscribe in parallel (line 13).&lt;/p&gt;  &lt;p&gt;you can find different suggestion of how to complete such task in &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/rx/thread/635834a4-87fe-455e-8733-3d2129899d58?prof=required" target="_blank"&gt;this&lt;/a&gt; thread. &lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;both Scan and Aggregate are a very useful operators,&lt;/p&gt;  &lt;p&gt;but you should be careful while using it within a Window.&amp;#160; &lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Rx-Aggregate-vs-Scan-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F01%2F24%2Frx-aggregate-vs-scan.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=996264" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /><category term="scan" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/scan/default.aspx" /><category term="aggregate" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/aggregate/default.aspx" /></entry><entry><title>Rx - Exception Handling</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/22/rx-exception-handling.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/22/rx-exception-handling.aspx</id><published>2012-01-22T18:07:56Z</published><updated>2012-01-22T18:07:56Z</updated><content type="html">&lt;h2&gt;Rx - Exception Handling&lt;/h2&gt;  &lt;p&gt;this post will discuss &lt;strong&gt;exception handling&lt;/strong&gt; within the &lt;strong&gt;Rx&lt;/strong&gt; arena.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_3501-small_5746BB8E.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, observable, observer, linq, exception handling, try, catch, finally, retry" border="0" alt="Rx, observable, observer, linq, exception handling, try, catch, finally, retry" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_3501-small_thumb_6E717465.png" width="435" height="317" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;handling event stream exception is not trivial,    &lt;br /&gt;for example &lt;strong&gt;observable&lt;/strong&gt; should delegate exception to its subscribers though the &lt;strong&gt;OnError&lt;/strong&gt; operation and &lt;strong&gt;cancel&lt;/strong&gt; the &lt;strong&gt;subscription&lt;/strong&gt;.     &lt;br /&gt;on the other hand the &lt;strong&gt;subscriber&lt;/strong&gt; may want to response &lt;strong&gt;OnError&lt;/strong&gt; state by &lt;strong&gt;renewing&lt;/strong&gt; its &lt;strong&gt;subscription&lt;/strong&gt; or &lt;strong&gt;fallback&lt;/strong&gt; to &lt;strong&gt;alternative stream&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;it is true that the &lt;strong&gt;Rx design guidelines&lt;/strong&gt; suggest that faulted stream should not continue to produce data,     &lt;br /&gt;but real-world implementation such as stuck exchange stream (or other hot stream) may ignore this recommendation.&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;if you design such stream you can consider having a fault info, wrapped within the OnNext message (as a data property) instead of sending OnError state and leaving the OnError state for fatal fault which the stream cannot be recover from.&lt;/font&gt;&lt;/p&gt;  &lt;h5&gt;So how can you handle fault state?&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;Rx&lt;/strong&gt; is having a few &lt;strong&gt;operator&lt;/strong&gt; that response to &lt;strong&gt;OnError&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the first one is &lt;strong&gt;Retry&lt;/strong&gt; which &lt;strong&gt;re-subscribe&lt;/strong&gt; (forever or for specific number of failures).&lt;/p&gt;  &lt;p&gt;for the Demonstration I will use the following observable (which produce OnError after the second OnNext):&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:15e93f57-26ca-4d50-bb16-52ffc38c70bb" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; observable = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Create&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    obs =&amp;gt;&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        obs.OnNext(1);&lt;/li&gt; &lt;li&gt;        obs.OnNext(2);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        obs.OnError(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SystemException&lt;/span&gt;());&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Disposable&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    });&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the following code &lt;strong&gt;re-subscribe 3 times&lt;/strong&gt; before it do surrender to the evil exception.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4ad58b21-dd6d-4c44-b735-ac703af17b97" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2em;padding:0 0 0 5px;"&gt; &lt;li&gt;observable&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    .Retry(3)&lt;/li&gt; &lt;li&gt;    .Subscribe(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(item),&lt;/li&gt; &lt;li&gt;        (ex) =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(ex.Message),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Complete&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&lt;font color="#666666"&gt;this scenario may be suitable for observable which download data from the network and response with an error when the network is not available (consider unreliable network).&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;the output will look like the following snapshot:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/EH1_5742A78F.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, observable, observer, linq, exception handling, try, catch, finally, retry" border="0" alt="Rx, observable, observer, linq, exception handling, try, catch, finally, retry" src="http://blogs.microsoft.co.il/blogs/bnaya/EH1_thumb_3BBDA58C.png" width="318" height="237" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;sometimes it is not enough to re-subscribe and you have to define an &lt;strong&gt;alternative fallback stream&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;consider stock exchange scenario, when ever specific stock provider has fail to supply the data you may want to switch and subscribe to different provider.&lt;/p&gt;  &lt;p&gt;you can do so using the &lt;strong&gt;Catch&lt;/strong&gt; operator:&lt;/p&gt;  &lt;p&gt;just like &lt;strong&gt;try catch&lt;/strong&gt; you can specify specific or have generic fallback strategy.&lt;/p&gt;  &lt;p&gt;having the following fallback streams:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7bfe7d97-67da-4f3b-b6ab-e9ca04e6d4d5" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; fallback1 = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Create&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    obs =&amp;gt;&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 10; i++)&lt;/li&gt; &lt;li&gt;            obs.OnNext(i);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Disposable&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li&gt;    });&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; fallback2 = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Create&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li&gt;    obs =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 20; i &amp;lt; 23; i++)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            obs.OnNext(i);&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Disposable&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    });&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; fallback3 = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Create&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    obs =&amp;gt;&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 30; i &amp;lt; 33; i++)&lt;/li&gt; &lt;li&gt;            obs.OnNext(i);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Disposable&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li&gt;    });&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;you can &lt;strong&gt;map the fallback&lt;/strong&gt; using the following Rx code:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:23dcc974-4a78-4873-bff5-964c673a3c51" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2em;padding:0 0 0 5px;"&gt; &lt;li&gt;observable&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    .Catch((&lt;span style="color:#2b91af;"&gt;NullReferenceException&lt;/span&gt; ex) =&amp;gt; fallback1)&lt;/li&gt; &lt;li&gt;    .Catch((&lt;span style="color:#2b91af;"&gt;SystemException&lt;/span&gt; ex) =&amp;gt; fallback2)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    .Catch(fallback3)&lt;/li&gt; &lt;li&gt;    .Subscribe(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(item),&lt;/li&gt; &lt;li&gt;        (ex) =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(ex.Message),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Complete&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;lines 2-4 are mapping different fallbacks for different exceptions.&lt;/p&gt;  &lt;p&gt;it will generate the following output:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/EH2_2A89C7E9.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, observable, observer, linq, exception handling, try, catch, finally, retry" border="0" alt="Rx, observable, observer, linq, exception handling, try, catch, finally, retry" src="http://blogs.microsoft.co.il/blogs/bnaya/EH2_thumb_481BA2E8.png" width="315" height="233" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;SystemException has thrown, therefore the fallback stream is starting at 20.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;finally&lt;/strong&gt; we can discuss the 3rd option.&lt;/p&gt;  &lt;p&gt;sometimes you do not care whether the stream has stopped because it has complete or was faulted, all you really care about is to &lt;strong&gt;clear some resources&lt;/strong&gt;.     &lt;br /&gt;in this case you can use the &lt;strong&gt;finally&lt;/strong&gt; operator which will be trigger in both scenario, completed normally or in faulted state.&lt;/p&gt;  &lt;p&gt;the following code demonstrate this API:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1fba94aa-b816-490a-aaf4-b532c5b996c6" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;observable&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    .Finally(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* clear some resources */}&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;    .Subscribe(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(item),&lt;/li&gt; &lt;li&gt;        (ex) =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(ex.Message),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Complete&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;Rx has some very useful operator which response to the OnError state, you can re-subscribe, switch into fallback stream of just handle the finalization state.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Rx-Exception-Handling-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F01%2F22%2Frx-exception-handling.aspx" /&gt;&lt;/a&gt; &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblogs.microsoft.co.il%2fblogs%2fbnaya%2farchive%2f2012%2f01%2f22%2frx-exception-handling.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=994972" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /><category term="observer" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/observer/default.aspx" /><category term="finally" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/finally/default.aspx" /><category term="retry" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/retry/default.aspx" /><category term="observable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/observable/default.aspx" /><category term="exception handling" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/exception+handling/default.aspx" /><category term="linq" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/linq/default.aspx" /><category term="try" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/try/default.aspx" /><category term="catch" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/catch/default.aspx" /></entry><entry><title>async / await, some reasoning</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/19/async-await-some-reasoning.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/19/async-await-some-reasoning.aspx</id><published>2012-01-19T09:09:23Z</published><updated>2012-01-19T09:09:23Z</updated><content type="html">&lt;h2&gt;async / await, some reasoning&lt;/h2&gt;  &lt;p&gt;this post will try to make some reasoning about the &lt;strong&gt;.NET 4.5 / C#5 await&lt;/strong&gt; keyword.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_6498_small_50439CCB.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="async, await, task, tpl, parallel, c#5, .NET 4.5" border="0" alt="async, await, task, tpl, parallel, c#5, .NET 4.5" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_6498_small_thumb_5CC1241A.png" width="339" height="230" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I will begin with a quiz.&lt;/p&gt;  &lt;p&gt;how long will it take to the following method to produce the 42 value?&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:67a78d27-306f-4098-8621-b0f2bb0bdc82" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Delay(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Delay(1000);&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; 42;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;you should remember that conceptually the &lt;strong&gt;await&lt;/strong&gt; keyword will translate to a &lt;strong&gt;continuation&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the above code can be compare to the following &lt;strong&gt;TPL 4&lt;/strong&gt; code snippet:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ca0e8452-65f9-434b-a932-2f214c8ef0c7" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000));&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t2 = t1.ContinueWith(t1_ =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        });&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; t3 = t2.ContinueWith(t2_ =&amp;gt; 42);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; t3;&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;whatever come after the &lt;strong&gt;await&lt;/strong&gt; will be compile into a &lt;strong&gt;continuation closure&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;therefore the 42 value will be produce after &lt;strong&gt;2 second&lt;/strong&gt;.&lt;/p&gt;  &lt;h5&gt;How can we await for multiple task?&lt;/h5&gt;  &lt;p&gt;there is couple of way for &lt;strong&gt;awaiting&lt;/strong&gt; on &lt;strong&gt;multiple tasks&lt;/strong&gt;, but the most recommended one is to use Task.&lt;strong&gt;WhenAll&lt;/strong&gt; (you can also use&lt;strong&gt; &lt;/strong&gt;Task.&lt;strong&gt;WhenAny&lt;/strong&gt; to continue after the completion of the first task).&lt;/p&gt;  &lt;p&gt;&lt;font color="#666666"&gt;&lt;em&gt;do not confuse the Task.&lt;strong&gt;WhenAll&lt;/strong&gt; with Task.&lt;strong&gt;WaitAll, WhenAll&lt;/strong&gt; is a continuation which happens when all the task come to completion, while &lt;strong&gt;WaitAll&lt;/strong&gt; is a blocking API which will block the execution until all tasks will be completed&lt;/em&gt;.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;the following snippet demonstrate the Task.&lt;strong&gt;WhenAll&lt;/strong&gt; usage.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4ba378e0-0468-430b-bd58-49df1a733ed8" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Delay(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t2 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Delay(1000);&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.WhenAll(t1, t2);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; 42;&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the 42 value will now produce after &lt;strong&gt;1 second&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;it is somewhat equals to the following &lt;strong&gt;TPL 4&lt;/strong&gt; snippet:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:885dc749-3806-4412-bf71-730d307676ed" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000));&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t2 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000));&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; t3 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.ContinueWhenAll(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt;[]{t1, t2}, tsks =&amp;gt; 42);&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; t3;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;to wrap it up let think how long will it take to the following snippet to produce a value.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d8078248-512c-4284-9ebe-7ab2bfdfdce7" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 10; i++)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Delay(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; 42;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the right answer is 10 seconds, each iteration will result in a continuation closure which will wrap the following iterations.&lt;/p&gt;  &lt;p&gt;this can be translate to something like the following snippet (&lt;strong&gt;TPL 4&lt;/strong&gt;).&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:86275192-eaa8-4e3d-8386-31ba63cc824e" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; stateMachine = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;StateMachine&lt;/span&gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; stateMachine.OnNext();&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;StateMachine&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; _i;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TaskCompletionSource&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; _semanticTask =&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TaskCompletionSource&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; OnNext()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Interlocked&lt;/span&gt;.Increment(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; _i);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000));&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_i &amp;lt;= 10)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            t.ContinueWith(t_ =&amp;gt; OnNext());&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            _semanticTask.SetResult(42);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _semanticTask.Task;&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the execute method will create a state machine which will &lt;strong&gt;chain task continuation 10 times&lt;/strong&gt; and then set the value of 42.     &lt;br /&gt;the &lt;strong&gt;TaskCompletionSource&lt;/strong&gt; represent semantics of task (TAP - Task Async Pattern).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;font color="#666666"&gt;TaskCompletionSource&lt;/font&gt;&lt;/strong&gt; &lt;font color="#666666"&gt;does not produce any concurrency (doesn&amp;#39;t attached to any thread), it just present a task which can be project result, exception or cancellation.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;the OnNext method immediately return a semantic task which will signal as complete at line 22 (the exit term of the recursion).&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;await&lt;/strong&gt; present a &lt;strong&gt;continuation&lt;/strong&gt;. each time the code is hitting the await it construct a new continuation closure.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/async-await-some-reasoning-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F01%2F19%2Fasync-await-some-reasoning.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=992172" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="async" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/async/default.aspx" /><category term="await" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/await/default.aspx" /><category term="TAP" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TAP/default.aspx" /><category term=".NET 4.5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/.NET+4.5/default.aspx" /><category term="C#5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/C_2300_5/default.aspx" /></entry><entry><title>Using async / await</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/15/using-async-await.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/15/using-async-await.aspx</id><published>2012-01-14T22:46:58Z</published><updated>2012-01-14T22:46:58Z</updated><content type="html">&lt;h2&gt;Using async / await&lt;/h2&gt;  &lt;p&gt;this post will discuss parallel disposal.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_9746_2168_small_1F348538.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="async, await, parallel, task,tpl, using" border="0" alt="async, await, parallel, task,tpl, using" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_9746_2168_small_thumb_5D0DCA5C.png" width="334" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;whenever we want to &lt;strong&gt;dispose&lt;/strong&gt; a &lt;strong&gt;parallel execution&lt;/strong&gt; upon completion we can&amp;#39;t use the convenient &lt;strong&gt;using&lt;/strong&gt; keyword.&lt;/p&gt;  &lt;p&gt;for example, the following code may be dispose the command before completion:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9e272259-3eb9-47d2-b059-2b06b2d0d4cd" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Very bad Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; conn = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt;(CONN_STR))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; cmd = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Select * from Employee&amp;quot;&lt;/span&gt;, conn)) &lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    conn.Open();&lt;/li&gt; &lt;li&gt;    cmd.BeginExecuteReader(ar =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; affected = cmd.EndExecuteNonQuery(ar);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        });&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the &lt;strong&gt;using&lt;/strong&gt; is absolutely wrong for the above sample.&lt;/p&gt;  &lt;p&gt;what should be done is:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:549dca5a-4369-48a4-99b2-c5dab5b1eb96" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; conn = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt;(CONN_STR);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; cmd = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Select * from Employee&amp;quot;&lt;/span&gt;, conn);&lt;/li&gt; &lt;li&gt;conn.Open();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;cmd.BeginExecuteReader(ar =&amp;gt;&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; affected = cmd.EndExecuteNonQuery(ar);&lt;/li&gt; &lt;li&gt;    cmd.Dispose();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    conn.Dispose();&lt;/li&gt; &lt;li&gt;}, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;we can write it slightly friendlier by using the TPL FromAsync wrapper:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:17352ac0-7dff-4f25-85a9-5ae6029242ac" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; conn = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt;(CONN_STR);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; cmd = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Select * from Employee&amp;quot;&lt;/span&gt;, conn);&lt;/li&gt; &lt;li&gt;conn.Open();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.FromAsync&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li&gt;    cmd.BeginExecuteReader,&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    cmd.EndExecuteNonQuery,&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;t.ContinueWith(tsk =&amp;gt;&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; affected = tsk.Result;&lt;/li&gt; &lt;li&gt;        cmd.Dispose();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        conn.Dispose();&lt;/li&gt; &lt;li&gt;    });&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;h5&gt;but what if the compiler can rewrite our code?&lt;/h5&gt;  &lt;p&gt;in that case we can write a similar code to the code in the first code snippet and get it compiled into something like the above code snippet above.&lt;/p&gt;  &lt;p&gt;this is exactly what happens when in&lt;strong&gt; .NET 4.5 / C#5&lt;/strong&gt; (&lt;strong&gt;async / await pattern&lt;/strong&gt;).&lt;/p&gt;  &lt;p&gt;when we write the following code:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e7dedbdc-7d82-49dc-8fa5-d71f6539012f" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; ExecuteNonQueryAsync()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; affected = 0;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; conn = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlConnection&lt;/span&gt;(CONN_STR))&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; cmd = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlCommand&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Select * from Employee&amp;quot;&lt;/span&gt;, conn))&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        conn.Open();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        affected = &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.FromAsync&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(&lt;/li&gt; &lt;li&gt;            cmd.BeginExecuteReader,&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            cmd.EndExecuteNonQuery,&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; affected;  &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the compiler does rewrite this async method.&lt;/p&gt;  &lt;p&gt;everything that follow the await keyword (line 8), &lt;/p&gt;  &lt;p&gt;will be put into a continuation state machine, including the closing of the curly brackets (of the using).&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;using the new async / await pattern will dispose our resources on time.&lt;/p&gt;  &lt;p&gt;using keyword is a very clean syntax and now we can apply it to parallel execution.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Using-async-await-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F01%2F15%2Fusing-async-await.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=987991" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="async" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/async/default.aspx" /><category term="await" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/await/default.aspx" /><category term="continuewith" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/continuewith/default.aspx" /><category term="continuation" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/continuation/default.aspx" /><category term=".NET 4.5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/.NET+4.5/default.aspx" /><category term="C#5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/C_2300_5/default.aspx" /><category term="using" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/using/default.aspx" /></entry><entry><title>async \ await and Exception Handling</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/12/async-await-and-exception-handling.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/12/async-await-and-exception-handling.aspx</id><published>2012-01-12T06:11:07Z</published><updated>2012-01-12T06:11:07Z</updated><content type="html">&lt;h2&gt;async \ await and Exception Handling&lt;/h2&gt;  &lt;p&gt;this post will discuss how &lt;strong&gt;async / await&lt;/strong&gt; is &lt;strong&gt;handling exceptions&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_1829_small_72A36ABC.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="async, await, continuation, continue,exception, tpl,.net 4.5, c#5" border="0" alt="async, await, continuation, continue,exception, tpl,.net 4.5, c#5" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_1829_small_thumb_60A68B55.png" width="242" height="269" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;as we mention in previous &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/29/the-concept-of-async-await.aspx" target="_blank"&gt;post&lt;/a&gt;, about the &lt;strong&gt;async / await&lt;/strong&gt; concept, &lt;strong&gt;await is all about continuation&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;before .NET 4.5 parallel execution exceptions has to be handle in separate of the synchronic handling.&lt;/p&gt;  &lt;p&gt;for example:&lt;/p&gt;  &lt;p&gt;handling ThreadPool execution:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cadffb80-4f21-42ec-b433-ab46acaa8e21" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Foo()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Synchronic&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;ThreadPool&lt;/span&gt;.QueueUserWorkItem(state =&amp;gt;&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li&gt;                {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Parallel&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;                }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; exAsync)&lt;/li&gt; &lt;li&gt;                {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                    &lt;span style="color:#2b91af;"&gt;EventLog&lt;/span&gt;.WriteEntry(&lt;span style="color:#a31515;"&gt;&amp;quot;application&amp;quot;&lt;/span&gt;, exAsync.ToString());&lt;/li&gt; &lt;li&gt;                }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            }, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;EventLog&lt;/span&gt;.WriteEntry(&lt;span style="color:#a31515;"&gt;&amp;quot;application&amp;quot;&lt;/span&gt;, ex.ToString());&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;as you can see we have to handle the parallel exception (line 12) in separate from the synchronic handling (line 18).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TPL&lt;/strong&gt; has brought new option for handling parallel exception, now you can use &lt;strong&gt;ContinueWith&lt;/strong&gt; with &lt;strong&gt;TaskContinuationOptions.OnlyOnFault &lt;/strong&gt;(line 8).     &lt;br /&gt;but still you have to handle the parallel exception is in separate of the synchronic one:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a5cc18e1-f3b5-407f-b94f-4c5600395331" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Foo()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Synchronic&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Parallel&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li&gt;        t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;EventLog&lt;/span&gt;.WriteEntry(&lt;span style="color:#a31515;"&gt;&amp;quot;application&amp;quot;&lt;/span&gt;, tsk.Exception.ToString()), &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;TaskContinuationOptions&lt;/span&gt;.OnlyOnFaulted);&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;EventLog&lt;/span&gt;.WriteEntry(&lt;span style="color:#a31515;"&gt;&amp;quot;application&amp;quot;&lt;/span&gt;, ex.ToString());&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;async / await pattern&lt;/h5&gt;  &lt;p&gt;using the async / await pattern we can handle both synchronic and parallel exception in the same place:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c95c67bf-6fd4-495d-88a8-0a641cd8a920" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Foo()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Synchronic&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Parallel&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#008000;"&gt;// handling both synchronic and parallel exceptions&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;EventLog&lt;/span&gt;.WriteEntry(&lt;span style="color:#a31515;"&gt;&amp;quot;application&amp;quot;&lt;/span&gt;, ex.ToString());&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;when we are using the &lt;strong&gt;async / await&lt;/strong&gt; pattern at &lt;strong&gt;compile time&lt;/strong&gt; the compiler convert our code into continuation state machine.     &lt;br /&gt;therefore the compiler can take the code within the catch area and apply it both for the synchronic and the parallel execution.&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;async / await pattern does simplify the exception handling. we do write our exception handling once and it will apply for both synchronic and parallel execution.&lt;/p&gt; &lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fblogs.microsoft.co.il%2fblogs%2fbnaya%2farchive%2f2012%2f01%2f12%2fasync-await-and-exception-handling.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=985364" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="async" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/async/default.aspx" /><category term="await" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/await/default.aspx" /><category term="continuation" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/continuation/default.aspx" /><category term=".NET 4.5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/.NET+4.5/default.aspx" /><category term="C#5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/C_2300_5/default.aspx" /><category term="exception" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/exception/default.aspx" /><category term="continue" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/continue/default.aspx" /></entry><entry><title>Rx - Sample</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/05/rx-sample.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/05/rx-sample.aspx</id><published>2012-01-05T17:45:27Z</published><updated>2012-01-05T17:45:27Z</updated><content type="html">&lt;h2&gt;Rx - Sample&lt;/h2&gt;  &lt;p&gt;this post will focus on the Rx &lt;strong&gt;Sample&lt;/strong&gt; operator.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/Sample_76765F5D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="IObservable,IObserver,Sample,Rx,Reactive" border="0" alt="IObservable,IObserver,Sample,Rx,Reactive" src="http://blogs.microsoft.co.il/blogs/bnaya/Sample_thumb_47905B21.png" width="422" height="292" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;Sample&lt;/strong&gt; operation does sampling the observable stream and &lt;strong&gt;forward less&lt;/strong&gt; &lt;strong&gt;intensive data stream&lt;/strong&gt; of the sampled datum.&lt;/p&gt;  &lt;p&gt;it can be prove very useful for scenario like handling    &lt;br /&gt;&lt;strong&gt;accelerometer&lt;/strong&gt; stream which can produce 60 value per second, in some cases we don&amp;#39;t need such intensity and     &lt;br /&gt;our machine resources may be happier to handle only 10 value per seconds.     &lt;br /&gt;the same may be apply to &lt;strong&gt;video stream&lt;/strong&gt; &lt;strong&gt;analytics&lt;/strong&gt; and many other scenario.&lt;/p&gt;  &lt;p&gt;this is how the marble diagram look like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_504017D3.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="IObservable,IObserver,Sample,Rx,Reactive" border="0" alt="IObservable,IObserver,Sample,Rx,Reactive" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_4703DC92.png" width="469" height="119" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;as you can see, nothing special it is just a time based filtering.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;Sample&amp;#39;s&lt;/strong&gt; &lt;strong&gt;API&lt;/strong&gt; is:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2d2f0913-104e-42f3-9067-df199539ba3b" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(0.1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; ys = xs.Sample(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(30));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the TimeSpan parameter define the sampling rate.&lt;/p&gt;  &lt;p&gt;except of the TimeSpan overload the Sample operator    &lt;br /&gt;can be &lt;strong&gt;triggered&lt;/strong&gt; &lt;strong&gt;upon&lt;/strong&gt; a &lt;strong&gt;custom timing&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;custom triggering is done by using an overload which accept &lt;strong&gt;IObservable&lt;/strong&gt; as it &lt;strong&gt;sampling trigger&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the following example is using a random stream of data as the Sample trigger:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ed48e059-73e7-469d-b16f-bcf4a659978d" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; rndStream = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Create&amp;lt;&lt;span style="color:#2b91af;"&gt;Unit&lt;/span&gt;&amp;gt;(obs =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; unsub = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;BooleanDisposable&lt;/span&gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; rand = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Random&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;                &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!unsub.IsDisposed)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                {&lt;/li&gt; &lt;li&gt;                    &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(rand.Next(4000));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                    obs.OnNext(&lt;span style="color:#2b91af;"&gt;Unit&lt;/span&gt;.Default);&lt;/li&gt; &lt;li&gt;                }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            });&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; unsub;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    });&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(0.1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; ys = xs.Sample(rndStream);&lt;/li&gt; &lt;li&gt;ys.Subscribe(item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:#a31515;"&gt;&amp;quot;{0}, &amp;quot;&lt;/span&gt;, item));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;as you can see ,at line 16, the xs stream will be sampled at random rate.&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;Sample is very straight forward operator which bring the ability of reducing stream intensity in cases which a lower data rate is better.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Rx-Sample-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2012%2F01%2F05%2Frx-sample.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=980224" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="Performance" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Performance/default.aspx" /><category term="Reactive" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /><category term="Sample" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Sample/default.aspx" /></entry><entry><title>Rx - Window</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/31/rx-window.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/31/rx-window.aspx</id><published>2011-12-31T08:16:57Z</published><updated>2011-12-31T08:16:57Z</updated><content type="html">&lt;h2&gt;Rx - Window&lt;/h2&gt;  &lt;p&gt;continuing with the &lt;strong&gt;Rx&lt;/strong&gt; series, this post will discuss the &lt;strong&gt;Window&lt;/strong&gt; operator. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_4193_2D36F468.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" border="0" alt="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_4193_thumb_61B70509.png" width="389" height="329" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;in previous &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/22/rx-buffer.aspx" target="_blank"&gt;post&lt;/a&gt; I was discussing the &lt;strong&gt;Buffer &lt;/strong&gt;operator which enable buffering of Rx datum stream into chunks.&lt;/p&gt;  &lt;p&gt;has good and useful as the &lt;strong&gt;Buffer&lt;/strong&gt; operator is, it doesn&amp;#39;t nail up every single scenario.&lt;/p&gt;  &lt;p&gt;let consider a scenario of tracing the &lt;strong&gt;highest&lt;/strong&gt; and &lt;strong&gt;lower&lt;/strong&gt; value &lt;strong&gt;within a time period&lt;/strong&gt;. for example hourly tracking of a service monitoring which produce values every second.&lt;/p&gt;  &lt;p&gt;technically we can use the &lt;strong&gt;Buffer&lt;/strong&gt; operator for handling this scenario. the problem is that buffering a hour of data for each of our services will end up with 3660 long living items for each of the services.&lt;/p&gt;  &lt;p&gt;this will lead us to:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;item which survive the GC Gen 0,1 collection. &lt;/li&gt;    &lt;li&gt;large object heap allocation in case large chunks. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;the point is that in this scenario &lt;strong&gt;buffering&lt;/strong&gt; the data is &lt;strong&gt;doesn&amp;#39;t needed at all&lt;/strong&gt;, because calculating the highest and lower value can be done on the fly by comparing the current value against the previous one.&lt;/p&gt;  &lt;h5&gt;The right operator for this scenario&lt;/h5&gt;  &lt;p&gt;so we need some kind of window (&lt;font color="#666666"&gt;either of a time period, fix item count or the combination of the 2&lt;/font&gt;) which will project value within it scope without buffering.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Rx&lt;/strong&gt; does have such operator which is the &lt;strong&gt;Window&lt;/strong&gt; operator. &lt;/p&gt;  &lt;p&gt;in contrast to the &lt;strong&gt;Buffer&lt;/strong&gt; operator which return &lt;strong&gt;IObservable&amp;lt;IList&amp;lt;T&amp;gt;&amp;gt;&lt;/strong&gt; the &lt;strong&gt;Window&lt;/strong&gt; operator return &lt;strong&gt;IObservable&amp;lt;IObservable&amp;lt;T&amp;gt;&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;at first glance it seem rather odd signature, but I will right about to show how powerful is this concept and how can you take advantage of it.&lt;/p&gt;  &lt;p&gt;but before we will get into the implementation details we rather take a look on the differences between the &lt;strong&gt;Buffer&lt;/strong&gt; and &lt;strong&gt;Window&lt;/strong&gt; operators.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;Buffer &lt;/strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/02/28/rx-for-beginners-part-5-marble-diagrams-select-and-where.aspx" target="_blank"&gt;&lt;strong&gt;marble diagram&lt;/strong&gt;&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_3C7660C0.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" border="0" alt="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_40A03885.png" width="387" height="216" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;buffer accumulate the item&lt;/strong&gt; internally until the end of its buffering period and then project the accumulated values as &lt;strong&gt;IList&amp;lt;T&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;Window&lt;/strong&gt; marble diagram is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_6B2BF395.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" border="0" alt="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_08519BA0.png" width="477" height="220" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;unlike the &lt;strong&gt;Buffer&lt;/strong&gt;, which is &lt;strong&gt;caching&lt;/strong&gt; the &lt;strong&gt;item&lt;/strong&gt; internally, the &lt;strong&gt;Window&lt;/strong&gt; does &lt;strong&gt;not cache&lt;/strong&gt; the items at all, each item is immediately project through &lt;strong&gt;IObservable&amp;lt;T&amp;gt;.OnNext&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Window support sliding window and the custom periods API, just like the Buffer operator do (read more on that at the &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/22/rx-buffer.aspx" target="_blank"&gt;Buffer&lt;/a&gt; operator post).&lt;/p&gt;  &lt;p&gt;sliding Window will share the same item in multiple windows:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_0FAD5B4D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" border="0" alt="Rx, Reactive Extension,Window,Buffer, IObservable, IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_7A6F2FD7.png" width="444" height="271" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h5&gt;Better memory utilization&lt;/h5&gt;  &lt;p&gt;back to our initial goal, the following code is using an &lt;strong&gt;Aggregate&lt;/strong&gt; operator over a &lt;strong&gt;Window&lt;/strong&gt; and calculate the min / max value for each period.&lt;/p&gt;  &lt;p&gt;I will use the following class of aggregation&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c62e2cb5-1573-4832-9bfd-f49bcebc829b" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;long&lt;/span&gt;? Min { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;long&lt;/span&gt;? Max { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt; Calc(&lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt; instance, &lt;span style="color:#0000ff;"&gt;long&lt;/span&gt; value)&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!instance.Min.HasValue)&lt;/li&gt; &lt;li&gt;            {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                instance.Min = value;&lt;/li&gt; &lt;li&gt;                instance.Max = value;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            }&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            {&lt;/li&gt; &lt;li&gt;                instance.Min = &lt;span style="color:#2b91af;"&gt;Math&lt;/span&gt;.Min(instance.Min.Value, value);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                instance.Max = &lt;span style="color:#2b91af;"&gt;Math&lt;/span&gt;.Max(instance.Max.Value, value);&lt;/li&gt; &lt;li&gt;            }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; instance;&lt;/li&gt; &lt;li&gt;        }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;and the following code demonstrate the plumbing:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9d2bbc55-3f96-4fc8-a9cd-7f36ba15aff8" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(0.1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;&amp;gt; minMax = &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; win &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; xs.Window(10)&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; item &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; win.Aggregate(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;(), &lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;.Calc)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; item;&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;minMax.Subscribe (item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#a31515;"&gt;&amp;quot;Min = {0} /tMax = {1}&amp;quot;&lt;/span&gt;,&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    item.Min.Value, item.Max.Value));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the above code snippet is using the &lt;strong&gt;from&lt;/strong&gt; keyword &lt;strong&gt;twice&lt;/strong&gt; (line 4 and 5) which is in fact using the &lt;strong&gt;SelectMany&lt;/strong&gt; operator. it is used to extract the inner &lt;strong&gt;IObservable&amp;lt;T&amp;gt;&lt;/strong&gt; out of the &lt;strong&gt;IObservable&amp;lt;IObservable&amp;lt;T&amp;gt;&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;other alternative is to use the &lt;strong&gt;Switch&lt;/strong&gt; operator, which also extract the inner &lt;strong&gt;IObservable&amp;lt;T&amp;gt;&lt;/strong&gt; out of &lt;strong&gt;Coverable&amp;lt;IObservable&amp;lt;T&amp;gt;&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;in this case the code will look like:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bd70a6e6-db9f-4642-8c20-243f9925fea9" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;&amp;gt;&amp;gt; minMax =&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;from&lt;/span&gt; win &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; xs.Window(10)&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;select&lt;/span&gt; win.Aggregate(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;(),&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;MinMaxItem&lt;/span&gt;.Calc);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;minMax.Switch().Subscribe(item =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#a31515;"&gt;&amp;quot;Min = {0} /tMax = {1}&amp;quot;&lt;/span&gt;,&lt;/li&gt; &lt;li&gt;    item.Min.Value, item.Max.Value));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;notice the &lt;strong&gt;Switch&lt;/strong&gt; operator at line 7.&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;I have shown the &lt;strong&gt;Window&lt;/strong&gt; operator and it&amp;#39;s capabilities.&lt;/p&gt;  &lt;p&gt;because &lt;strong&gt;IObservable&amp;lt;IObservable&amp;lt;T&amp;gt;&amp;gt; &lt;/strong&gt;is quit a complex API, &lt;strong&gt;Window&lt;/strong&gt; is usually come with other operator like &lt;strong&gt;Aggregate, SelectMany&lt;/strong&gt; or other operator which I will discuss on latter posts.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;Switch&lt;/strong&gt; operator is very handy when you want to flatten the &lt;strong&gt;Window&lt;/strong&gt; output (it is simply merge the inner observable streams into single result).&lt;/p&gt;  &lt;p&gt;an alternative to &lt;strong&gt;Switch&lt;/strong&gt; is the &lt;strong&gt;SelectMany&lt;/strong&gt; operator which can handle each of the &lt;strong&gt;Window&lt;/strong&gt; streams separately (it can be used directly or by the &lt;strong&gt;nested from&lt;/strong&gt; syntax).&lt;/p&gt;  &lt;p&gt;you can read more on Window memory benefit on &lt;strong&gt;James Miles&amp;#39;s &lt;/strong&gt;&lt;a href="http://enumeratethis.com/2011/07/26/financial-charts-reactive-extensions/" target="_blank"&gt;post&lt;/a&gt; about using &lt;strong&gt;Rx Window&lt;/strong&gt; in stock exchange scenario.&lt;/p&gt;  &lt;h5&gt;&lt;font style="font-weight:normal;"&gt;and be aware of some &lt;font style="font-weight:bold;"&gt;parallelism issues &lt;/font&gt;involve with Window, Aggregate and SelectMany which &lt;/font&gt;&lt;font style="font-weight:normal;"&gt;you can read more about in &lt;a href="http://www.delicious.com/redirect?url=http%3A//social.msdn.microsoft.com/Forums/en-US/rx/thread/635834a4-87fe-455e-8733-3d2129899d58%3Fprof%3Drequired" target="_blank"&gt;this&lt;/a&gt; thread of the &lt;font style="font-weight:bold;"&gt;Rx forum &lt;/font&gt;which discuss some of the &lt;font style="font-weight:bold;"&gt;pitfall&lt;/font&gt;, API request and alternative API for the window aggregation scenario.&lt;/font&gt;&lt;/h5&gt;  &lt;p&gt;finally you should use the operator that is most appropriate for your scenario, for example the &lt;strong&gt;Buffer&lt;/strong&gt; operator is great for balance IO operations, and the &lt;strong&gt;Window&lt;/strong&gt; operator is great to reduce memory pressure upon aggregation. &lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/Rx-Window-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2011%2F12%2F31%2Frx-window.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=974470" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /><category term="Buffer" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Buffer/default.aspx" /><category term="Window" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Window/default.aspx" /></entry><entry><title>the concept of async \ await</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/29/the-concept-of-async-await.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/29/the-concept-of-async-await.aspx</id><published>2011-12-29T15:41:42Z</published><updated>2011-12-29T15:41:42Z</updated><content type="html">&lt;h2&gt;the concept of async \ await&lt;/h2&gt;  &lt;p&gt;in this post I will survey the new .NET 4.5 / C# 5 concept of async / await.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/IMG_2101-small_58EC151B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="async, await, .NET 4.5, C#5, continuation" border="0" alt="async, await, .NET 4.5, C#5, continuation" src="http://blogs.microsoft.co.il/blogs/bnaya/IMG_2101-small_thumb_06F59F6F.png" width="371" height="316" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I will focus on how to understand what is really happens behind the new &lt;strong&gt;async / await&lt;/strong&gt; syntax.&lt;/p&gt;  &lt;h5&gt;What&amp;#39;s it all about?&lt;/h5&gt;  &lt;p&gt;the new &lt;strong&gt;async / await &lt;/strong&gt;syntax is using the C# syntactic compiler to generate &lt;strong&gt;async operation&lt;/strong&gt; from code that is looking very much &lt;strong&gt;like a synchronous&lt;/strong&gt; code.&lt;/p&gt;  &lt;p&gt;but before we start we should discus the new C# 5&amp;#160; syntax.&lt;/p&gt;  &lt;p&gt;the syntax include 2 keywords:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;async&lt;/strong&gt; - which is only a marker for async method. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;await&lt;/strong&gt; - indicate a callback boundary. &lt;/li&gt; &lt;/ul&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5895840e-138b-401c-9704-2a3fa47b4ace" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(run on calling thread);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(run on callback thread); &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;so how should we understand what was written in the above code?&lt;/p&gt;  &lt;p&gt;actually it is a different way to represent a &lt;strong&gt;continuation&lt;/strong&gt; (you can read more about the continuation concept in &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/28/tpl-continuation.aspx" target="_blank"&gt;here&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;the above code is somewhat identical to the following TPL 4 code:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cb5a075e-4cf3-4cc3-8696-c220bb5b29df" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(run on calling thread);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000));&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; t.ContinueWith (tsk =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;              &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(run on callback thread);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        });&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the &lt;strong&gt;syntactic compiler&lt;/strong&gt; will translate the code below the await keyword into &lt;strong&gt;continuation&lt;/strong&gt; &lt;strong&gt;state machine&lt;/strong&gt;, which is logically (not technically) identical to the above code.&lt;/p&gt;  &lt;h5&gt;Point of interest:&lt;/h5&gt;  &lt;p&gt;you may have been notice that the async method return a &lt;strong&gt;Task&lt;/strong&gt; even though there is no return within the method block.     &lt;br /&gt;surveying the TPL 4 code snippet we can understand that the async method will actually return to the caller immediately after the &lt;strong&gt;Task.Factory.StartNew&lt;/strong&gt; start the task and the rest of the code is actually a &lt;strong&gt;continuation callback&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;what we got back from the async method is a &lt;strong&gt;task&lt;/strong&gt; which represent the &lt;strong&gt;async part of the method&lt;/strong&gt;.&lt;/p&gt;  &lt;h5&gt;async / await with return value&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;async / await&lt;/strong&gt; can represent a continuation of a callback that accept async result.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c8d7ba84-d088-4fe6-b3b3-231a4c4aab83" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;async&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt; result = &lt;span style="color:#0000ff;"&gt;await&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now );&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;      &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; result.AddDays(1);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the above code will logically translate to:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4503bc00-ebfb-4f7c-ac52-12c5cafedae1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;&amp;gt; Execute()&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;&amp;gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;DateTime&lt;/span&gt;.Now);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; t.ContinueWith (tsk =&amp;gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;              &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; tsk.Result.AddDays(1);&lt;/li&gt; &lt;li&gt;        });&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;you may have notice that the &lt;strong&gt;return value&lt;/strong&gt; (&lt;font color="#666666"&gt;on the left side of the await&lt;/font&gt;) was &lt;strong&gt;unwrapped&lt;/strong&gt; (&lt;font color="#666666"&gt;DateTime instead of Task&amp;lt;DateTime&amp;gt;&lt;/font&gt;) &lt;/p&gt;  &lt;h5&gt;Which thread is running?&lt;/h5&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/async1_0DF4904D.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="async, await, .NET 4.5, C#5, continuation" border="0" alt="async, await, .NET 4.5, C#5, continuation" src="http://blogs.microsoft.co.il/blogs/bnaya/async1_thumb_57C2F230.png" width="583" height="252" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;normally when the method doesn&amp;#39;t invoke from the UI thread, everything &lt;strong&gt;before the await&lt;/strong&gt; line will run &lt;strong&gt;synchronously&lt;/strong&gt; on the caller thread.     &lt;br /&gt;the &lt;strong&gt;Task.Run&lt;/strong&gt; naturally will be &lt;strong&gt;schedule&lt;/strong&gt; on a &lt;strong&gt;different thread &lt;/strong&gt;and everything &lt;strong&gt;under the await&lt;/strong&gt; will be &lt;strong&gt;schedule&lt;/strong&gt; on &lt;strong&gt;different thread&lt;/strong&gt; then the caller thread, it may be the same thread of the Task.Run or any other ThreadPool thread (&lt;font color="#666666"&gt;when there is only single continuation it will probably be the same thread as Task.Run&lt;/font&gt;) &lt;/p&gt;  &lt;h5&gt;Async and UI&lt;/h5&gt;  &lt;p&gt;whenever the async method invocation is coming from &lt;strong&gt;UI thread&lt;/strong&gt; (or to be more precise from thread under synchronization context) the continuation return back to the &lt;strong&gt;synchronization context thread&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;this is quit similar to the following TPL code (.NET 4):&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:42302151-dba0-486a-9c98-ef565065f3d1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;TaskScheduler&lt;/span&gt; scheduler = &lt;span style="color:#2b91af;"&gt;TaskScheduler&lt;/span&gt;.FromCurrentSynchronizationContext();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;span style="color:#2b91af;"&gt;Trace&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;in parallel&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Trace&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;UI thread&amp;quot;&lt;/span&gt;), scheduler);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;or to more legacy code which is using the synchronization context directly:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:be8d81d0-b478-4c96-a1c4-f1748185dbdb" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt; a = () =&amp;gt; &lt;span style="color:#2b91af;"&gt;Trace&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;in parallel&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;SynchronizationContext&lt;/span&gt; sc = &lt;span style="color:#2b91af;"&gt;SynchronizationContext&lt;/span&gt;.Current;&lt;/li&gt; &lt;li&gt;a.BeginInvoke(ar =&amp;gt; &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        sc.Post(state =&amp;gt; &lt;span style="color:#2b91af;"&gt;Trace&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;UI thread&amp;quot;&lt;/span&gt;), &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;&lt;strong&gt;async / await&lt;/strong&gt; is aware of the &lt;strong&gt;synchronization context&lt;/strong&gt; of the caller and if any it &lt;strong&gt;schedule&lt;/strong&gt; the &lt;strong&gt;await&lt;/strong&gt; &lt;strong&gt;callback&lt;/strong&gt; on this context.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/async2_3F03A520.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="async, await, .NET 4.5, C#5, continuation" border="0" alt="async, await, .NET 4.5, C#5, continuation" src="http://blogs.microsoft.co.il/blogs/bnaya/async2_thumb_41E8E406.png" width="575" height="212" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;the &lt;strong&gt;syntactic compiler translate&lt;/strong&gt; the&lt;strong&gt; async / await&lt;/strong&gt; syntax into state machine which handle the continuation flow after parallel operation.&lt;/p&gt;  &lt;p&gt;there is much more for that and I will discuss it in future posts.&lt;/p&gt;  &lt;p&gt;you can see it performance characteristic on &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/15/what-is-the-cost-of-async-await.aspx" target="_blank"&gt;this&lt;/a&gt; post.&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/the-concept-of-async-await-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2011%2F12%2F29%2Fthe-concept-of-async-await.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=972828" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Performance" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Performance/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="async" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/async/default.aspx" /><category term="await" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/await/default.aspx" /><category term="continuewith" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/continuewith/default.aspx" /><category term="TAP" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TAP/default.aspx" /><category term="continuation" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/continuation/default.aspx" /><category term=".NET 4.5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/.NET+4.5/default.aspx" /><category term="C#5" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/C_2300_5/default.aspx" /></entry><entry><title>TPL - Continuation</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/28/tpl-continuation.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/28/tpl-continuation.aspx</id><published>2011-12-28T17:10:59Z</published><updated>2011-12-28T17:10:59Z</updated><content type="html">&lt;h2&gt;TPL - Continuation&lt;/h2&gt;  &lt;p&gt;this post will discuss &lt;strong&gt;TPL Continuation&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/domino_51BD63FD.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Tpl, Continuation, continuewith,task" border="0" alt="Tpl, Continuation, continuewith,task" src="http://blogs.microsoft.co.il/blogs/bnaya/domino_thumb_1C347C0B.jpg" width="244" height="184" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TPL&lt;/strong&gt; &lt;strong&gt;continuation&lt;/strong&gt; can chain task into a &lt;strong&gt;pipeline&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;when dealing with dependencies between parallel work units, like [encoding -&amp;gt; compression -&amp;gt; encryption], continuation is the API for &lt;strong&gt;scheduling&lt;/strong&gt; work unit &lt;strong&gt;upon completion&lt;/strong&gt; of other work unit.&lt;/p&gt;  &lt;p&gt;the general idea is quit similar to the old APM pattern (&lt;font color="#666666"&gt;BeginXxx, EndXxx&lt;/font&gt;) callback.&lt;/p&gt;  &lt;h5&gt;basic completion&lt;/h5&gt;  &lt;p&gt;the syntax of continuation:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:78a2cdee-cb7a-4b10-aa3a-278e56dd99fa" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tsk = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do somethng*/}&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;tsk.ContinueWith(t =&amp;gt; {&lt;span style="color:#008000;"&gt;/* continue when something complete*/}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;continuation API is fairly straight-forward:&lt;/p&gt;  &lt;p&gt;we can define a continuation action upon task completion (the t in the lambda represent the completed task).&lt;/p&gt;  &lt;h5&gt;completion of Task&amp;lt;T&amp;gt;&lt;/h5&gt;  &lt;p&gt;continuation does also support &lt;strong&gt;Task&amp;lt;T&amp;gt;&lt;/strong&gt; this way we can handle a task result upon the task&amp;#39;s completion.&lt;/p&gt;  &lt;p&gt;the following sample show the concept of the [encoding -&amp;gt; encryption -&amp;gt; send] pipeline:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3c770ba2-a5ff-401d-a2a3-d5e9f3b3aa01" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;byte&lt;/span&gt;[]&amp;gt; tskEncoding = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Encoding&lt;/span&gt;.UTF8.GetBytes(data);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;});&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;Byte&lt;/span&gt;[]&amp;gt; tskEncrypt  = tskEncoding.ContinueWith(t =&amp;gt; &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Encrypt(t.Result);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;});&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tskSend = tskEncoding.ContinueWith(t =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    Send(t.Result);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;});&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the first task (line 1-4) return (async) encoding data.&lt;/p&gt;  &lt;p&gt;the first continuation task (line 5-8) get the encoded data from the result of the completed task and encrypt it, the encrypted data return as the task&amp;#39;s result.&lt;/p&gt;  &lt;p&gt;the second continuation (line 9-12) will be schedule on the completion of the encryption task.&lt;/p&gt;  &lt;h5&gt;multiple completions&lt;/h5&gt;  &lt;p&gt;completion API does not limit to single completion per a task. the completion represent a callback and we can set as many callback as we need for any Task (or Task&amp;lt;T&amp;gt;).&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6e05fdc8-1f7b-4f60-bc5a-977a420b5cc4" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tsk = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do somethng*/}&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;tsk.ContinueWith(t =&amp;gt; {&lt;span style="color:#008000;"&gt;/* callback 1 */}&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;tsk.ContinueWith(t =&amp;gt; {&lt;span style="color:#008000;"&gt;/* callback 2 */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;Continue when all/any&lt;/h5&gt;  &lt;p&gt;we can also set continuation which will be trigger upon the completion of multiple tasks.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9f6e5b9c-1235-4880-921a-b61130679409" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tsk1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do somethng */}&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tsk2 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do somethng else */}&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;[] tsks = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;[] { tsk1, tsk2 };&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.ContinueWhenAll(tsks, tskArr =&amp;gt; {&lt;span style="color:#008000;"&gt;/* callback 1 */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;or continue on the completion of the first among multiple tasks.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:26d7539d-3468-45ea-8e77-3a3ad190ac09" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tsk1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do somethng */}&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; tsk2 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do somethng else */}&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;[] tsks = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;[] { tsk1, tsk2 };&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.ContinueWhenAny(tsks, firstTask =&amp;gt; {&lt;span style="color:#008000;"&gt;/* callback 1 */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;Parent / Child&lt;/h5&gt;  &lt;p&gt;as you may know TPL support a parent / child execution model,    &lt;br /&gt;when you start a task within an executing task scope you can set the task behavior to accept the parent / child paradigm.     &lt;br /&gt;the TPL infrastructure does aware when a task is having children and behave accordantly (&lt;font color="#666666"&gt;wait will wait for the completion of all the task&amp;#39;s children, cancelling a parent task will affect all of its children, the debug parallel tasks window can present the task&amp;#39;s hierarchic&lt;/font&gt;).&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8ce4852f-4fe2-413c-a4e0-c28709da7255" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        },&lt;span style="color:#2b91af;"&gt;TaskCreationOptions&lt;/span&gt;.AttachedToParent);&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;});&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;Parent / Child and continuation&lt;/h5&gt;  &lt;p&gt;when it come to continuation the continuation callback will occurs only after the completion of all the task&amp;#39;s children.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:66066a65-aea5-4389-80d7-a024217a3603" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;child1&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;    }, &lt;span style="color:#2b91af;"&gt;TaskCreationOptions&lt;/span&gt;.AttachedToParent);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;});&lt;/li&gt; &lt;li&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Complete !!!&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the above code demonstrate a simple continuation upon parent child task.&lt;/p&gt;  &lt;p&gt;the completion will occurs when after the completion of t1.&lt;/p&gt;  &lt;h5&gt;Parent / child with nested continuation&lt;/h5&gt;  &lt;p&gt;let take another scenario when both the parent and the child task is having a continuation.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4f197b81-b013-4455-b93c-d9d9aaa3ba8e" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;child1&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;    }, &lt;span style="color:#2b91af;"&gt;TaskCreationOptions&lt;/span&gt;.AttachedToParent);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    t1.ContinueWith(tsk =&amp;gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;child continuation&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        });            &lt;/li&gt; &lt;li&gt;});&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;parent continuation&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;let think of the above code. will the parent continuation complete before or after the child continuation?&lt;/p&gt;  &lt;p&gt;the answer is: the parent continuation will ignore the child continuation and complete first.&lt;/p&gt;  &lt;p&gt;the parent continuation will be aware of the child continuation only if we mark the child continuation with &lt;strong&gt;TaskContinuationOptions.AttachedToParent&lt;/strong&gt;.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0594daec-b0a9-4c5c-b3aa-49b7aa3e5715" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t1 = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;child1&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;    }, &lt;span style="color:#2b91af;"&gt;TaskCreationOptions&lt;/span&gt;.AttachedToParent);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    t1.ContinueWith(tsk =&amp;gt;&lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;child continuation&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        }, &lt;span style="color:#2b91af;"&gt;TaskContinuationOptions&lt;/span&gt;.AttachedToParent);            &lt;/li&gt; &lt;li&gt;});&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;parent continuation&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;now the parent continuation will complete after the completion of the child&amp;#39;s task continuation.&lt;/p&gt;  &lt;h5&gt;Conditional continuation&lt;/h5&gt;  &lt;p&gt;till now we have seen many of the continuation scenarios. the last scenario which I want to present is the cool ability of tuning the continuation to occurs only when the &lt;strong&gt;execution status end with specific condition&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;you can set the continuation to occur only on success, failure or cancellation.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4a655216-4915-430a-b727-f5f6f1f033d9" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; cancellation = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;CancellationTokenSource&lt;/span&gt;();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt; &lt;/li&gt; &lt;li&gt;    {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Environment&lt;/span&gt;.TickCount % 2 == 0)&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt;(); &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;pass&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    }, cancellation.Token);&lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;OK&amp;quot;&lt;/span&gt;), &lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;TaskContinuationOptions&lt;/span&gt;.OnlyOnRanToCompletion);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Cancelled&amp;quot;&lt;/span&gt;),&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;TaskContinuationOptions&lt;/span&gt;.OnlyOnCanceled);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;t.ContinueWith(tsk =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Failed&amp;quot;&lt;/span&gt;), &lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;TaskContinuationOptions&lt;/span&gt;.OnlyOnFaulted);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the &lt;strong&gt;TaskContinuationOptions&lt;/strong&gt; is a bitwise so you can specify multiple option upon single continuation.&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;continuation is one of the most powerful feature of the new TPL infrastructure.&lt;/p&gt;  &lt;p&gt;it is having more feature and it simpler to use than the old APM pattern.&lt;/p&gt;  &lt;p&gt;using the continuation pattern we can manage complex parallelism with regard of dependencies.&lt;/p&gt;  &lt;p&gt;finally ,as I will describe in latter past, the new async&amp;#160; feature (of .NET 4.5 / C#5) is all about the continuation concept. &lt;/p&gt;  &lt;br /&gt;&lt;a href="http://dotnetshoutout.com/TPL-Continuation-Bnaya-Eshet"&gt;&lt;img style="border-right-width:0px;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fblogs.microsoft.co.il%2Fblogs%2Fbnaya%2Farchive%2F2011%2F12%2F28%2Ftpl-continuation.aspx" /&gt;&lt;/a&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=971866" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="TAP" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TAP/default.aspx" /></entry><entry><title>Rx - SP1</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/25/rx-sp1.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/25/rx-sp1.aspx</id><published>2011-12-25T07:24:07Z</published><updated>2011-12-25T07:24:07Z</updated><content type="html">&lt;h2&gt;RX - SP1&lt;/h2&gt;  &lt;p&gt;Rx release is having it first service pack.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/rx_2346AD56.jpg"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="rx, SP, IObservable, IObserver" border="0" alt="rx, SP, IObservable, IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/rx_thumb_3ADD9922.jpg" width="348" height="83" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The Service Pack release doesn&amp;#39;t include any new API-level functionality and &lt;strong&gt;fixes a few minor bugs&lt;/strong&gt; (all of which were already fixed in the Experimental Releases in the v1.1 band):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Scheduler.TaskPool now guarantees the use of the task pool. See this &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/rx/thread/5a7fd5cf-073f-45d1-a4d4-93a80dac390a"&gt;forum post&lt;/a&gt; for more info. &lt;/li&gt;    &lt;li&gt;SkipUntil now propagates errors of the source sequence, even when the &amp;quot;until&amp;quot; sequence hasn&amp;#39;t fired yet. &lt;/li&gt;    &lt;li&gt;ToQbservable now accepts an IScheduler parameter, mirroring its ToObservable brother. &lt;/li&gt;    &lt;li&gt;Take(0) is now supported, resulting in an overload that accepts an IScheduler to produce the OnCompleted message.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In addition to those fixes, this (supported) release includes &lt;strong&gt;support for Silverlight 5 and Windows Phone 7.5&lt;/strong&gt;, so you&amp;#39;ll find the Rx assemblies in the Add New Reference dialog for those project types.&lt;/p&gt;  &lt;p&gt;When using the MSI installer, you&amp;#39;ll notice the installer performs an &lt;strong&gt;in-place update&lt;/strong&gt; of any existing Rx SDK v1.0.10621 installation you may have on your machine. If you don&amp;#39;t have the v1.0 SDK installed yet, you can simply use the new MSI to perform a clean install as well.&lt;/p&gt;  &lt;p&gt;Assembly version numbers (used by the CLR) continue to be 1.0.10621.0, hence you don&amp;#39;t need to recompile applications that use Rx v1.0 but you can simply service the Rx binaries. The file version number (used by installers to upgrade files) of the assemblies has bumped to 1.0.11221.5 (reflecting the build date, i.e. December 21st, precisely six months after the initial release). Also, the version number of the MSI package and NuGet packages will reflect the 11221 build number.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=968340" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="IQbservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IQbservable/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /></entry><entry><title>Rx - Buffer</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/22/rx-buffer.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/22/rx-buffer.aspx</id><published>2011-12-22T18:40:49Z</published><updated>2011-12-22T18:40:49Z</updated><content type="html">&lt;h2&gt;Rx - Buffer&lt;/h2&gt;  &lt;p&gt;this post is on of a series of post about &lt;strong&gt;Rx&lt;/strong&gt; (Reactive Extension). in this one I will discuss the &lt;strong&gt;Buffer&lt;/strong&gt; operator.&lt;/p&gt;  &lt;p&gt;no doubt that one of the &lt;strong&gt;most useful Rx operator&lt;/strong&gt; is the &lt;strong&gt;Buffer&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/MC900382608_7BE6C845.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Buffer,Rx,Reactive,IObservable,IObserver" border="0" alt="Buffer,Rx,Reactive,IObservable,IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/MC900382608_thumb_00A93068.jpg" width="240" height="240" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the Buffer operator enable to &lt;strong&gt;reduce &lt;/strong&gt;a &lt;strong&gt;throughput pressure &lt;/strong&gt;and gain &lt;strong&gt;better utilization&lt;/strong&gt; of our resources. &lt;/p&gt;  &lt;p&gt;let take a scenario of &lt;strong&gt;monitoring data stream&lt;/strong&gt; and &lt;strong&gt;persist the datum&lt;/strong&gt; into database (or send it through a network boundaries). &lt;/p&gt;  &lt;p&gt;assuming the datum rate is 1 per millisecond, databases does not typically design to work well for round-trips of such frequency,    &lt;br /&gt;but if we can &lt;strong&gt;buffer a chunk of datum each second&lt;/strong&gt; (or more) we can save those chunk in much lower frequency (maybe by using bulk insert).&lt;/p&gt;  &lt;p&gt;this is how we can gain &lt;strong&gt;better utilization&lt;/strong&gt; of our system.&lt;/p&gt;  &lt;p&gt;this is exactly what the &lt;strong&gt;Buffer&lt;/strong&gt; operator does.     &lt;br /&gt;it can create&lt;strong&gt; chunk of data&lt;/strong&gt; from an &lt;strong&gt;observable&lt;/strong&gt; either by &lt;strong&gt;time or by count&lt;/strong&gt; (or even by the combination of both).&lt;/p&gt;  &lt;p&gt;it present those chunk as &lt;strong&gt;observable&lt;/strong&gt; of &lt;strong&gt;IList&amp;lt;T&amp;gt;&lt;/strong&gt; which mean that if we are dealing with &lt;strong&gt;high frequency Observable&amp;lt;T&amp;gt;&lt;/strong&gt; we can transform it to &lt;strong&gt;less frequently Observable&amp;lt;IList&amp;lt;T&amp;gt;&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the Buffer operator is very &lt;strong&gt;simple&lt;/strong&gt; to use and very &lt;strong&gt;flexible&lt;/strong&gt; in term of the batch size.&lt;/p&gt;  &lt;h5&gt;Buffer API&lt;/h5&gt;  &lt;p&gt;the following example demonstrates reducing pressure of 1 millisecond frequency observable:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7d4195eb-36d5-48ee-9235-e6cbfa0d9c2e" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bufferdStream = xs.Buffer(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1));&lt;/li&gt; &lt;li&gt;bufferdStream.Subscribe(item =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do bulk insert */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the same can be done with buffering for every n items:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4014a21c-0e40-49c9-827f-1b3b971208c8" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bufferdStream = xs.Buffer(1000);&lt;/li&gt; &lt;li&gt;bufferdStream.Subscribe(item =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do bulk insert */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;there is even API for the combination of both, which mean that the &lt;strong&gt;buffer&lt;/strong&gt; will be&lt;strong&gt; close, either after n item&lt;/strong&gt; or &lt;strong&gt;elapsed&lt;/strong&gt; of a&lt;strong&gt; duration&lt;/strong&gt;:&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8205e5a0-43db-4e5e-9692-b6d5176374fd" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bufferdStream = xs.Buffer(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1), 1000);&lt;/li&gt; &lt;li&gt;bufferdStream.Subscribe(item =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do bulk insert */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;the &lt;strong&gt;Buffer&lt;/strong&gt; operator &lt;strong&gt;can be overlapped&lt;/strong&gt;, which mean that more than one buffer can coexist at a time (datum will be capture by multiple buffers)&lt;/p&gt;    &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:335d051a-1777-4875-b8d9-b463d469951d" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; xs = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#008000;"&gt;// buffer window of 1 second will be open every 0.1 second&lt;/span&gt;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bufferdStream = xs.Buffer(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(1),&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;                            &lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromSeconds(0.1));&lt;/li&gt; &lt;li&gt;bufferdStream.Subscribe(item =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do bulk insert */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;    &lt;p&gt;the &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2010/02/28/rx-for-beginners-part-5-marble-diagrams-select-and-where.aspx" target="_blank"&gt;marble diagram&lt;/a&gt; of it is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/image_7DB3CBB4.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="Rx,Buffer,IObservable,IObserver" border="0" alt="Rx,Buffer,IObservable,IObserver" src="http://blogs.microsoft.co.il/blogs/bnaya/image_thumb_0F43B680.png" width="448" height="347" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;you can see that each buffer hold 4 datum and the same datum can be include in multiple buffers (IList&amp;lt;T&amp;gt;).&lt;/p&gt;  &lt;h5&gt;Advance Buffer API&lt;/h5&gt;  &lt;p&gt;actually you can gain even &lt;strong&gt;better control&lt;/strong&gt; on the &lt;strong&gt;opening&lt;/strong&gt; and &lt;strong&gt;closing&lt;/strong&gt; of a buffering windows.&lt;/p&gt;  &lt;p&gt;the buffer window design to accept an &lt;strong&gt;observable&lt;/strong&gt; as the &lt;strong&gt;opening trigger&lt;/strong&gt; of the buffering window and a &lt;strong&gt;corresponding observable factory&lt;/strong&gt; for signaling the window&amp;#39;s &lt;strong&gt;closing trigger&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;even though this API look a bit odd it is very powerful.&lt;/p&gt;  &lt;p&gt;with this &lt;strong&gt;API&lt;/strong&gt; you can activate buffer as response for external situation. let think of a buffering stream which should buffer cars engine performance within separate geographical regions. we can start buffering each time the car GPS indicate a region border and close the buffer window on exiting the region.&lt;/p&gt;  &lt;p&gt;real life scenario often need this kind of granularity.&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;API&lt;/strong&gt; for this feature goes like this:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:47abff5e-0be4-406d-80a1-2a9341b3c6e1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; regionBorderStream = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Create&amp;lt;&lt;span style="color:#2b91af;"&gt;Unit&lt;/span&gt;&amp;gt;(obs =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#008000;"&gt;// read and analize gps data&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Disposable&lt;/span&gt;.Empty;&lt;/li&gt; &lt;li&gt;    });&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; carEngineStream = &lt;span style="color:#2b91af;"&gt;Observable&lt;/span&gt;.Interval(&lt;span style="color:#2b91af;"&gt;TimeSpan&lt;/span&gt;.FromMilliseconds(1));&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; bufferdStream = carEngineStream.Buffer(regionBorderStream, &lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    region =&amp;gt; regionBorderStream.Where(item =&amp;gt;  item == region));&lt;/li&gt; &lt;li&gt;bufferdStream.Subscribe(item =&amp;gt; {&lt;span style="color:#008000;"&gt;/* do bulk insert */}&lt;/span&gt;);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;regionBorderStream (at line 1) represent a stream of region passing notification.&lt;/p&gt;  &lt;p&gt;carEngineStream (at line 6) represent a car engine information stream.&lt;/p&gt;  &lt;p&gt;and the buffered stream (at line 7) is buffering the engine stream while open a buffer each time it enter a region, which mean whenever the regionBorderStream produce a value. the buffer will be close when we will exit the region.&lt;/p&gt;  &lt;p&gt;you may have notice that the above code does &lt;strong&gt;support multiple buffering&lt;/strong&gt; &lt;strong&gt;at a time&lt;/strong&gt;. you may enter the city region and then enter a sub region (for example New York and the Central Park or Beijing and the Forbidden City area).&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;Buffering is very powerful scenario.&lt;/p&gt;  &lt;p&gt;I will survey other operator on future post and we will discuss the advantage and disadvantage of the Buffer operator in compare with some of the other operators.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=965723" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Rx" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Rx/default.aspx" /><category term="IObserver" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObserver/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="IObservable" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IObservable/default.aspx" /><category term="Reactive" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive/default.aspx" /><category term="Reactive Extension" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Reactive+Extension/default.aspx" /><category term="Buffer" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Buffer/default.aspx" /></entry><entry><title>Tpl Dataflow (IDataflowBlock) - Part 5</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/19/tpl-dataflow-idataflowblock-part-5.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/19/tpl-dataflow-idataflowblock-part-5.aspx</id><published>2011-12-19T18:42:00Z</published><updated>2011-12-19T18:42:00Z</updated><content type="html">&lt;h2&gt;Tpl Dataflow (&lt;strong&gt;IDataflowBlock&lt;/strong&gt; ) - Part 5&lt;/h2&gt;  &lt;p&gt;the previous post discus the concept &lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/09/tpl-dataflow-part-2.aspx" target="_blank"&gt;ITargetBlock&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/10/tpl-dataflow-part-3.aspx" target="_blank"&gt;ISourceBlock&lt;/a&gt;,&lt;/strong&gt;     &lt;br /&gt;which is the &lt;strong&gt;TDF&lt;/strong&gt; &lt;strong&gt;consumer/Producer&lt;/strong&gt; contract.&lt;/p&gt;  &lt;p&gt;you can find all the post in this series under the &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TDF/default.aspx" target="_blank"&gt;TDF&lt;/a&gt; tag. &lt;/p&gt;  &lt;p&gt;this post focus on the &lt;strong&gt;IDataflowBlock&lt;/strong&gt; contract which is the&lt;strong&gt; life-time management&lt;/strong&gt; contract for all data-flow&amp;#39;s blocks.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/MC900238403_048720CC.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="IDataflowBlock" border="0" alt="IDataflowBlock" src="http://blogs.microsoft.co.il/blogs/bnaya/MC900238403_thumb_3D21A50C.jpg" width="232" height="176" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;the &lt;strong&gt;IDataflowBlock&lt;/strong&gt; define single property and 2 methods:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bb71d4ab-5648-4e2b-aa12-4110129aac16" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IDataflowBlock&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; Completion { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Complete();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Fault(&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; exception);&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;ending the processing of Dataflow block is done either by calling &lt;strong&gt;Complete&lt;/strong&gt;() or by &lt;strong&gt;Fault&lt;/strong&gt;() in cases that the data flow should exit into fault state.&lt;/p&gt;  &lt;p&gt;in case of &lt;strong&gt;Complete&lt;/strong&gt; the block will finish the processing of all messages that already in it&amp;#39;s inner buffer and decline (&lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/09/tpl-dataflow-part-2.aspx" target="_blank"&gt;DecliningPermanently&lt;/a&gt;) any incoming messages.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Fault&lt;/strong&gt;&amp;#160; put the block into faulty state and it does not schedule any messages from its inner buffer.&lt;/p&gt;  &lt;p&gt;the C&lt;strong&gt;ompletion&lt;/strong&gt; property is using the &lt;strong&gt;TAP&lt;/strong&gt; (&lt;font color="#666666"&gt;task asynchrony pattern&lt;/font&gt;) concept as it API for&lt;strong&gt; monitoring the block state&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;the completion property return a &lt;strong&gt;Task&lt;/strong&gt; which enable either &lt;strong&gt;waiting&lt;/strong&gt; (Wait) on, &lt;strong&gt;continuation &lt;/strong&gt;(ContinueWith) or &lt;strong&gt;await&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;the block will set the &lt;strong&gt;task completion&lt;/strong&gt; when it will complete the processing of all the messages within it inner buffer (or when finishing current executing messages in case of faulty state).&lt;/p&gt;  &lt;p&gt;because the block is using the &lt;strong&gt;task semantic&lt;/strong&gt; for it&amp;#39;s easy to handle block exceptions.&lt;/p&gt;  &lt;p&gt;the following code demonstrate the management of ActionBlock lifetime.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7a04b534-68cf-42ca-991e-ce01eea27d22" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; ab = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ActionBlock&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;(i =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(1000);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(i);&lt;/li&gt; &lt;li&gt;});&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;ab.Completion.ContinueWith(t =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (t.Status == &lt;span style="color:#2b91af;"&gt;TaskStatus&lt;/span&gt;.Faulted)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Failiur: {0}&amp;quot;&lt;/span&gt;, t.Exception);&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Complete&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li&gt;});&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Proccesing&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;ab.Post(1);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;ab.Post(2);&lt;/li&gt; &lt;li&gt;ab.Post(3);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadKey().KeyChar == &lt;span style="color:#a31515;"&gt;&amp;#39;f&amp;#39;&lt;/span&gt;)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    (ab &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IDataflowBlock&lt;/span&gt;).Fault(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;wrong tick&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    ab.Complete();&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;at line 7 we have set a continuation callback which check the completion status and writing the completion information.&lt;/p&gt;  &lt;h5&gt;point of interest&lt;/h5&gt;  &lt;p&gt;as we discuss in the previous post the dataflow blocks does have internal task which is responsible for its execution (by default it is one task per block but it can be throttle to work with multiple tasks) this task does release when ever the block become idle (when the block will become active again it will construct new task).&lt;/p&gt;  &lt;p&gt;it is important to understand that the completion task is a semantic task and not one of the worker tasks.&lt;/p&gt;  &lt;p&gt;in case that you want to create you&amp;#39;re own custom block you can use the TaskCompletionSource&amp;lt;T&amp;gt; in order to present the TAP (task asynchrony pattern) semantics.&lt;/p&gt;  &lt;p&gt;you can learn more on the TAP concept in &lt;a href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/18/task-thread.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;every dataflow block implement the IDataflowBlock contract which enable to control and monitor the block life-time.&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=961306" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Performance" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Performance/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="Dataflow" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Dataflow/default.aspx" /><category term="TDF" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TDF/default.aspx" /><category term="IDataflowBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/IDataflowBlock/default.aspx" /><category term="ISourceBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/ISourceBlock/default.aspx" /><category term="ITargetBlock" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/ITargetBlock/default.aspx" /><category term="TPL Dataflow" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL+Dataflow/default.aspx" /><category term="TAP" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TAP/default.aspx" /><category term="taskcompletionsource" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/taskcompletionsource/default.aspx" /></entry><entry><title>Task != Thread</title><link rel="alternate" type="text/html" href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/18/task-thread.aspx" /><id>http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/18/task-thread.aspx</id><published>2011-12-18T18:29:00Z</published><updated>2011-12-18T18:29:00Z</updated><content type="html">&lt;h2&gt;Task != Thread&lt;/h2&gt;  &lt;p&gt;whenever I teaching the &lt;strong&gt;Tpl Task&lt;/strong&gt; subject I continually repeating the mantra which say that &amp;quot;&lt;strong&gt;task is a metadata/context of execution and it does not really responsible for the actual execution&lt;/strong&gt;&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Task is a data structure&lt;/strong&gt; which hold information about code execution, it&amp;#39;s hold the delegate which will be execute, status, state, result, exception synchronization object, ext...     &lt;br /&gt;but the responsibility of the execution is actually belong to the &lt;strong&gt;Task Scheduler&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;in matter of fact task can be execute synchronously.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:74c231ff-3daa-46c7-9476-3c0facb90fb1" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.CurrentThread.ManagedThreadId);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt; t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;(() =&amp;gt; &lt;/li&gt; &lt;li&gt;    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.CurrentThread.ManagedThreadId));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;t.RunSynchronously();&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;by default it is execute on a thread pool worker thread but it can be execute on non thread pool thread (&lt;font color="#666666"&gt;using the TaskCreationOption.LongRunning overload&lt;/font&gt;).&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3c00c102-409c-4a0b-bc20-70eb5fdfe3d0" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.CurrentThread.IsThreadPoolThread));&lt;/li&gt; &lt;li&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;.Factory.StartNew(() =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.CurrentThread.IsThreadPoolThread),&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;TaskCreationOptions&lt;/span&gt;.LongRunning);&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;it can be benefit from &lt;a href="http://en.wikipedia.org/wiki/Input/output_completion_port" target="_blank"&gt;IOCP&lt;/a&gt; (IO Completion Port) in order to avoid thread pool starvation (&lt;font color="#666666"&gt;when performing IO operations&lt;/font&gt;).     &lt;br /&gt;IO operation are not CPU bounded operation, those operation performed by the hard disk controller, the network card, ext...&lt;/p&gt;  &lt;p&gt;we can apply task semantic to IO operation which is using the APM pattern by using Task.Factory.FromAsync&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:06826d77-56cf-417d-b9c0-45f99d1016ff" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#008000;"&gt;//Task&amp;lt;int&amp;gt; returns the number of bytes read&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; taskAsyncRead = &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;.Factory.FromAsync(&lt;/li&gt; &lt;li&gt;        file.BeginRead,  &lt;span style="color:#008000;"&gt;// begin invoke delegate&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        file.EndRead,    &lt;span style="color:#008000;"&gt;// end invoke delegate&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        buffer,          &lt;span style="color:#008000;"&gt;// read buffer&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        0,               &lt;span style="color:#008000;"&gt;// start index&lt;/span&gt;&lt;/li&gt; &lt;li&gt;        buffer.Length,   &lt;span style="color:#008000;"&gt;// length&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);           &lt;span style="color:#008000;"&gt;// optional state&lt;/span&gt;&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;this lead us to the most general abstraction of the task semantic which is &lt;strong&gt;TaskCompletionSource&amp;lt;T&amp;gt;&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;TaskCompletionSource&amp;lt;T&amp;gt; is a class that help us to apply TAP (&lt;font color="#666666"&gt;Task Asynchrony Pattern&lt;/font&gt;) semantic.&lt;/p&gt;  &lt;p&gt;in general we can use this class to apply a &lt;strong&gt;TAP semantic&lt;/strong&gt; for any operation.&lt;/p&gt;  &lt;p&gt;for example the following code apply a TAP semantics for &lt;strong&gt;WebClient&lt;/strong&gt; download:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:18118bee-0949-4eeb-bf11-8ead5a6af268" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; DownloadAsync(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; address)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; uri = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Uri&lt;/span&gt;(address);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#008000;"&gt;// present TAP semantics&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; tcs = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TaskCompletionSource&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;(); &lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; proxy = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;WebClient&lt;/span&gt;();&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#008000;"&gt;// handling the download async result&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    proxy.DownloadStringCompleted += (s, e) =&amp;gt; &lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (e.Cancelled)&lt;/li&gt; &lt;li&gt;                tcs.SetCanceled();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (e.Error != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/li&gt; &lt;li&gt;                tcs.SetException(e.Error);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/li&gt; &lt;li&gt;                tcs.SetResult(e.Result);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;            proxy.Dispose();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        };&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#008000;"&gt;// start downloading a-sync&lt;/span&gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    proxy.DownloadStringAsync(uri); &lt;/li&gt; &lt;li&gt;&amp;nbsp;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; tcs.Task; &lt;span style="color:#008000;"&gt;// does not wait for completion&lt;/span&gt;&lt;/li&gt; &lt;li&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;the TaskCompletionSource&amp;lt;T&amp;gt; has the following methods:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;SetCanceled&lt;/strong&gt;: apply cancellation semantic. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;SetException&lt;/strong&gt;: apply fault semantic. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;SetResult&lt;/strong&gt;: apply completion semantic. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;and it have a &lt;strong&gt;Task property&lt;/strong&gt; which &lt;strong&gt;encapsulate the TAP semantics&lt;/strong&gt; and can be hand back to the caller.&lt;/p&gt;  &lt;h5&gt;IOCP&lt;/h5&gt;  &lt;p&gt;because &lt;strong&gt;WebClient&lt;/strong&gt; async operation is using the &lt;strong&gt;IOCP&lt;/strong&gt; by wrapping it with &lt;strong&gt;TAP semantic&lt;/strong&gt; we gain a task which run over the IOCP.&lt;/p&gt;  &lt;h5&gt;Can we take it farther?&lt;/h5&gt;  &lt;p&gt;suppose we want to use a &lt;strong&gt;Task&lt;/strong&gt; which is trigger by &lt;strong&gt;FileSystemWatcher&lt;/strong&gt;. it is actually very feasible and easy when we are using the TaskCompletionSource&amp;lt;T&amp;gt;.&lt;/p&gt;  &lt;p&gt;the following extension method returns &lt;strong&gt;task&lt;/strong&gt; which will &lt;strong&gt;trigger when the user will delete text file&lt;/strong&gt;.&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7cc2adfc-fdef-4e68-ac31-1d5b7069f942" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; ToTask(&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FileSystemWatcher&lt;/span&gt; instance, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt; action)&lt;/li&gt; &lt;li&gt;{&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; tcs = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TaskCompletionSource&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt;();&lt;/li&gt; &lt;li&gt;    instance.EnableRaisingEvents = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    instance.Filter = &lt;span style="color:#a31515;"&gt;&amp;quot;*.txt&amp;quot;&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;    instance.Deleted += (s, e) =&amp;gt;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        {   &lt;/li&gt; &lt;li&gt;            action();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            tcs.SetResult(e.FullPath);&lt;/li&gt; &lt;li&gt;        };&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; tcs.Task;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;p&gt;then it can be call from anywhere:&lt;/p&gt;  &lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:541e45f1-809b-47c8-93e1-0d442c2e8e90" class="wlWriterEditableSmartContent"&gt; &lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt; &lt;div style="background:#000080;color:#fff;font-family:Verdana, Tahoma, Arial, sans-serif;font-weight:bold;padding:2px 5px;"&gt;Code Snippet&lt;/div&gt; &lt;div style="background:#fff;overflow:auto;"&gt; &lt;ol style="background:#ffffff;margin:0;padding:0 0 0 5px;"&gt; &lt;li&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] args)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;{&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; completed = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; fsw = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FileSystemWatcher&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    &lt;span style="color:#2b91af;"&gt;Task&lt;/span&gt;&amp;lt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;&amp;gt; t = fsw.ToTask(() =&amp;gt;&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Executing&amp;quot;&lt;/span&gt;));&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    t.ContinueWith(tsk =&amp;gt; &lt;/li&gt; &lt;li&gt;        {&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            completed = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/li&gt; &lt;li&gt;            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine();&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(tsk.Result);&lt;/li&gt; &lt;li&gt;        });&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;&amp;nbsp;&lt;/li&gt; &lt;li&gt;    &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!completed)&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;    {&lt;/li&gt; &lt;li&gt;        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(&lt;span style="color:#a31515;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;);&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;        &lt;span style="color:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(100);&lt;/li&gt; &lt;li&gt;    }&lt;/li&gt; &lt;li style="background:#f3f3f3;"&gt;}&lt;/li&gt; &lt;/ol&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt;  &lt;h5&gt;Summary&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;Task != Thread&lt;/strong&gt;, by default Task will be schedule on a thread pool thread but that is the responsibility of the task scheduler.&lt;/p&gt;  &lt;p&gt;the TAP abstraction does enable to apply its semantic to almost any operation.&lt;/p&gt;  &lt;p&gt;in future post I will show how to apply the &lt;strong&gt;FileSystemWatcher&lt;/strong&gt; to the &lt;strong&gt;async/await&lt;/strong&gt; pattern&lt;/p&gt;&lt;img src="http://blogs.microsoft.co.il/aggbug.aspx?PostID=959192" width="1" height="1"&gt;</content><author><name>bnaya</name><uri>http://blogs.microsoft.co.il/members/bnaya.aspx</uri></author><category term="DEV" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/DEV/default.aspx" /><category term="SELA" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/SELA/default.aspx" /><category term="Parallel" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Parallel/default.aspx" /><category term="Performance" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Performance/default.aspx" /><category term="Task" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Task/default.aspx" /><category term="Thread" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/Thread/default.aspx" /><category term="TPL" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TPL/default.aspx" /><category term="TAP" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/TAP/default.aspx" /><category term="taskcompletionsource" scheme="http://blogs.microsoft.co.il/blogs/bnaya/archive/tags/taskcompletionsource/default.aspx" /></entry></feed>
