<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Jeffrey rambles about Rx, .NET and programming in general.</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/jeffva/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/jeffva/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:08:12 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>jeffva.OnCompleted();</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/jeffva-oncompleted</link>
      <pubDate>Thu, 16 Dec 2010 16:24:24 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/12/16/jeffva-oncompleted/</guid>
      <description><![CDATA[After 11 years I've decided to leave Microsoft and start on a new endeavor. Because of this, I'll no...]]></description>
      <content:encoded><![CDATA[<p>After 11 years I've decided to leave Microsoft and start on a new endeavor. Because of this, I'll no longer be working on Rx. This will be my last blog post here. Thanks for all the people who've provided feedback! Please pester Erik, Bart and Wes to start posting more!</p>
<p>Catch me on twitter @jvgogh to keep in touch.</p>
<p>Thanks,</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Jeffrey&nbsp;</p>
<p>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type" />
</p>]]></content:encoded>
    </item>
    <item>
      <title>Rx on the server, part 5 of n: Observable ASP.NET</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/rx-on-the-server-part-5-of-n-observable-asp-net</link>
      <pubDate>Wed, 15 Sep 2010 11:28:18 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/09/15/rx-on-the-server-part-5-of-n-observable-asp-net/</guid>
      <description><![CDATA[(Reposted due to layout issues) Previously in these series we saw:   Reading a stream...]]></description>
      <content:encoded><![CDATA[<p></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">(Reposted due to layout issues)<br /></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Previously in these series we saw:</span></p> <ul> <li> <div class="MsoNormal"><span style="font-family: 'Segoe UI','sans-serif'"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx" target="_blank"><span style="color: #0066dd">Reading a stream asynchronously</span></a></span></div> </li><li> <div class="MsoNormal"><span style="font-family: 'Segoe UI','sans-serif'"></span><span style="font-family: 'Segoe UI','sans-serif'"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/26/rx-on-the-server-part-2-of-n-asynchronous-streamreader.aspx" target="_blank"><span style="color: #0066dd">Reading strings asynchronously, line by line</span></a><?xml:namespace prefix = o /><o:p></o:p></span><span style="font-family: 'Segoe UI','sans-serif'"></span></div> </li><li> <div class="MsoNormal"><span style="font-family: 'Segoe UI','sans-serif'"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/08/20/rx-on-the-server-part-3-of-n-writing-an-observable-to-a-stream.aspx"><span style="color: #0066dd">Writing an observable to a stream</span></a></span></div> </li><li> <div class="MsoNormal"><span style="font-family: 'Segoe UI','sans-serif'"></span><span style="font-family: 'Segoe UI','sans-serif'"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/08/30/rx-on-the-server-part-4-of-n-buffering-output-to-a-stream.aspx">Buffering output to a stream</a><o:p></o:p></span></div></li></ul> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">All previous posts dealt with interacting between observable and IO Streams. Next in these series, we’re going to take a look at a place we could use these operations in a real server appication: ASP.NET.<o:p></o:p></span></p> <h1><span style="mso-fareast-font-family: 'Times New Roman'">IHttpHandler<o:p></o:p></span></h1> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">ASP.NET provides a lot of functionality to make building webpages easy. This functionality can be grouped into different layers. At the bottom layer lies the technology that we’re going to focus in this post:<br />IHttpHandler.<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">IHttpHandler is the base interface that is used to expose request to the webserver to ASP.NET. It comes in two flavors: <a href="https://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx">IHttpHandler</a> and <a href="https://msdn.microsoft.com/en-us/library/system.web.ihttpasynchandler.aspx">IHttpAsyncHandler</a>. <br style="mso-special-character: line-break" /><br style="mso-special-character: line-break" /><o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">The reason for having the second version is exactly as <a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx">described in the beginning of these series</a>: scaling a webserver doesn’t work when blocking a whole thread for a single response.<br />In most webserver scenarios, a request will face many delays that are not processor bound, e.g.:</span></p> <ul> <li> <div class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Reading a file from (remote) disk</span></div> </li><li> <div class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span><span style="mso-fareast-font-family: 'Times New Roman'">Accessing a database<o:p></o:p></span></div></li></ul> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">As such, implementing IHttpAsyncHandler is often the best way to go. <o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Unfortunately, implementations of this interface can get very nasty. The interface itself follows the begin/end invoke pattern and when making multiple asynchronous calls as described above, coordinating these calls can get a nightmare.<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Let’s see if we can improve on this pattern.<o:p></o:p></span></p> <h1><span style="mso-fareast-font-family: 'Times New Roman'">ObservableHttpHandler<o:p></o:p></span></h1> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">At heart of this interface is the following set of operations:</span></p> <ul> <li> <div class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span><span style="mso-fareast-font-family: 'Times New Roman'">For each request send to a specified URL of the webserver, a method is called that will be responsible for processing this request.</span></div> </li><li> <div class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span><span style="mso-fareast-font-family: 'Times New Roman'">This method will receive an HttpContext object. This object provides information on the request and allows the method to send a response.</span></div> </li><li> <div class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span><span style="mso-fareast-font-family: 'Times New Roman'">The method can spin up any amount of asynchronous work to process the request.</span></div> </li><li> <div class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span><span style="mso-fareast-font-family: 'Times New Roman'">Once all asynchronous work is done and the response is sent, the method needs to signal it is done processing the request.<o:p></o:p></span></div></li></ul> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">In the Rx world, this can be modeled as follows:</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">I</span><span style="color: #2b91af">Observable</span>&lt;<span style="color: #2b91af">Unit</span>&gt; ProcessRequestAsObservable(<span style="color: #2b91af">HttpContext</span> context)<br /></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">As ASP.NET doesn’t know about this pattern, we’ll have to convert between the Asynchronous pattern it knows about (IHttpAsyncHandler) and the pattern we prefer.<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">We’ll create an abstract base class that will do this work for us.<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">First, we’ll implement the IHttpAsyncHandler interface. We’ll do this explicitly so these methods don’t show up in our public API surface.</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">abstract</span> <span style="color: blue">class</span> <span style="color: #2b91af">ObservableHttpHandler</span> : <span style="color: #2b91af">IHttpAsyncHandler<br /></span></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">abstract</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: #2b91af">Unit</span>&gt; ProcessRequestAsObservable(<span style="color: #2b91af">HttpContext</span> context);<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">IAsyncResult</span> <span style="color: #2b91af">IHttpAsyncHandler</span>.BeginProcessRequest(<span style="color: #2b91af">HttpContext</span> context, <br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">AsyncCallback</span> cb, <span style="color: blue">object</span> extraData)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">void</span> <span style="color: #2b91af">IHttpAsyncHandler</span>.EndProcessRequest(<span style="color: #2b91af">IAsyncResult</span> result)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">bool</span> <span style="color: #2b91af">IHttpHandler</span>.IsReusable<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span> { ... }<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">void</span> <span style="color: #2b91af">IHttpHandler</span>.ProcessRequest(<span style="color: #2b91af">HttpContext</span> context)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Let’s see how to implement these methods. We’ll start with the methods that IHttpAsyncHandler inherits from IHttpHandler:<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">IsReusable: return true as we don’t plan to maintain state in this class.<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">ProcessRequest: the method that is called if the request has to be processed synchronously. We will forward to the asynchronous version and block until the work has completed:</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">void</span> <span style="color: #2b91af">IHttpHandler</span>.ProcessRequest(<span style="color: #2b91af">HttpContext</span> context)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> gate = <span style="color: blue">new</span> <span style="color: #2b91af">ManualResetEvent</span>(<span style="color: blue">false</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">AsyncCallback</span> cb = (_ =&gt; gate.Set());<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((<span style="color: #2b91af">IHttpAsyncHandler</span>)<span style="color: blue">this</span>).BeginProcessRequest(context, cb, <span style="color: blue">null</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>gate.WaitOne();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><br style="mso-special-character: line-break" /><o:p></o:p></span></p> <h1><span style="mso-fareast-font-family: 'Times New Roman'">AsyncResult<o:p></o:p></span></h1> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">As the BeginProcessRequest method follows the begin/endinvoke pattern, we’ll have to return something that implements the <a href="https://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx">IAsyncResult</a> interface. So let’s start off with a simple implementation of this interface:</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">class</span> <span style="color: #2b91af">SimpleAsyncResult</span> : <span style="color: #2b91af">IAsyncResult<br /></span></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">ManualResetEvent</span> asyncWaitHandler;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: #2b91af">Exception</span> exception;<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> SimpleAsyncResult(<span style="color: blue">object</span> asyncState)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>AsyncState = asyncState;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncWaitHandler = <span style="color: blue">new</span> <span style="color: #2b91af">ManualResetEvent</span>(<span style="color: blue">false</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">object</span> AsyncState<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span>; <span style="color: blue">private</span> <span style="color: blue">set</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">WaitHandle</span> AsyncWaitHandle<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span> { <span style="color: blue">return</span> asyncWaitHandler; }<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">bool</span> CompletedSynchronously<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span> { <span style="color: blue">return</span> <span style="color: blue">false</span>; }<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">bool</span> IsCompleted<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">set</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">internal</span> <span style="color: blue">void</span> Success()<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Complete();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">internal</span> <span style="color: blue">void</span> Fail(<span style="color: #2b91af">Exception</span> exception)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span>.exception = exception;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Complete();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">void</span> Complete()<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>IsCompleted = <span style="color: blue">true</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncWaitHandler.Set();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">internal</span> <span style="color: blue">void</span> CheckResult()<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style="color: blue">if</span> (exception != <span style="color: blue">null</span>)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">throw</span> exception;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">SimpleAsyncResult will allow us to communicate to ASP.NET that the request has finished processing as well as pass along any exception that happened along the way.</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><strong></strong></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><strong>UPDATE: After posting this post, my coworker Stephen Toub from the TPL team pointed out, that instead of implementing SimpleAsyncResult, we could have reused Task as it also implements IAsyncResult. <br />I’ll leave it up as an exercise for the reader to do this.</strong></span></p> <h1><span style="mso-fareast-font-family: 'Times New Roman'">BeginProcessRequest<o:p></o:p></span></h1> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">The first thing we’ll do in BeginProcessRequest is to create an instance of this new class:</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> asyncResult = <span style="color: blue">new</span> <span style="color: #2b91af">SimpleAsyncResult</span>(extraData);</span><span style="font-family: consolas; font-size: 15.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Next we need to know how to kick off the computation. We’ll call the ProcessRequestAsObservable method and store the observable:<o:p></o:p></span></p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes"></span></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>var</span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"> observable = ProcessRequestAsObservable(context);<o:p></o:p></span></p> <p style="margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 15.5pt"><o:p></o:p></span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">Now it is time to kick off the computation by subscribing to the observable. As the observable only contains Unit values, we only care about completion either success or failure:<o:p></o:p></span></p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes"></span></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observable.Subscribe(<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_ =&gt; { },<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>e=&gt;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncResult.Fail(e);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cb(asyncResult);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}, <br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>() =&gt;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncResult.Success();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cb(asyncResult);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>});</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"></span>&nbsp;</p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">In both cases, we signal completion to the SimpleAsyncResult and call the callback that ASP.NET provided us. In the case of failure, we do provide the SimpleAsyncResult with the exception that occurred. <br /></span><span style="mso-fareast-font-family: 'Times New Roman'">Finally we’ll return the SimpleAsyncResult object back to ASP.NET:</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> asyncResult;</span></p> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'"><o:p></o:p></span></p> <h1><span style="mso-fareast-font-family: 'Times New Roman'">EndProcessRequest<o:p></o:p></span></h1> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">As the exception is now stuck as instance state in the SimpleAsyncResult instance, we’ll need to provide ASP.NET with a way to get the exception out of there. This is done by implementing the EndProcessRequest method:<o:p></o:p></span></p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; background: #eeece1; mso-bidi-font-size: 11.0pt; mso-shading-themecolor: background2"><span style="mso-spacerun: yes"></span></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; background: #eeece1; mso-bidi-font-size: 11.0pt; mso-shading-themecolor: background2"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>((<span style="color: #2b91af">SimpleAsyncResult</span>) result).CheckResult();</span><span style="mso-fareast-font-family: 'Times New Roman'"><o:p>&nbsp;</o:p></span></p> <h1><span style="mso-fareast-font-family: 'Times New Roman'">Complete Implementation<o:p></o:p></span></h1> <p class="MsoNormal"><span style="mso-fareast-font-family: 'Times New Roman'">With that the complete implementation of ObservableHttpHandler is:<o:p></o:p></span></p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes"></span></span>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">abstract</span> <span style="color: blue">class</span> <span style="color: #2b91af">ObservableHttpHandler</span> : <span style="color: #2b91af">IHttpAsyncHandler<br /></span></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">abstract</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: #2b91af">Unit</span>&gt; ProcessRequestAsObservable(<span style="color: #2b91af">HttpContext</span> context);<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">IAsyncResult</span> <span style="color: #2b91af">IHttpAsyncHandler</span>.BeginProcessRequest(<span style="color: #2b91af">HttpContext</span> context, <br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">AsyncCallback</span> cb, <span style="color: blue">object</span> extraData)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> asyncResult = <span style="color: blue">new</span> <span style="color: #2b91af">SimpleAsyncResult</span>(extraData);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> observable = ProcessRequestAsObservable(context);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observable.Subscribe(<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>_ =&gt; { },<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>e =&gt;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncResult.Fail(e);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cb(asyncResult);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>},<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>() =&gt;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncResult.Success();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>cb(asyncResult);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>});<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> asyncResult;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">void</span> <span style="color: #2b91af">IHttpAsyncHandler</span>.EndProcessRequest(<span style="color: #2b91af">IAsyncResult</span> result)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((<span style="color: #2b91af">SimpleAsyncResult</span>)result).CheckResult();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">bool</span> <span style="color: #2b91af">IHttpHandler</span>.IsReusable<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span> { <span style="color: blue">return</span> <span style="color: blue">true</span>; }<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">void</span> <span style="color: #2b91af">IHttpHandler</span>.ProcessRequest(<span style="color: #2b91af">HttpContext</span> context)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> gate = <span style="color: blue">new</span> <span style="color: #2b91af">ManualResetEvent</span>(<span style="color: blue">false</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">AsyncCallback</span> cb = (_ =&gt; gate.Set());<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>((<span style="color: #2b91af">IHttpAsyncHandler</span>)<span style="color: blue">this</span>).BeginProcessequest(context, cb, <span style="color: blue">null</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>gate.WaitOne();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">class</span> <span style="color: #2b91af">SimpleAsyncResult</span> : <span style="color: #2b91af">IAsyncResult<br /></span></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">readonly</span> <span style="color: #2b91af">ManualResetEvent</span> asyncWaitHandler;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: #2b91af">Exception</span> exception;<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> SimpleAsyncResult(<span style="color: blue">object</span> asyncState)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>AsyncState = asyncState;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncWaitHandler = <span style="color: blue">new</span> <span style="color: #2b91af">ManualResetEvent</span>(<span style="color: blue">false</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">object</span> AsyncState<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">set</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">WaitHandle</span> AsyncWaitHandle<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span> { <span style="color: blue">return</span> asyncWaitHandler; }<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">bool</span> CompletedSynchronously<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span> { <span style="color: blue">return</span> <span style="color: blue">false</span>; }<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">bool</span> IsCompleted<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">get</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">set</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">internal</span> <span style="color: blue">void</span> Success()<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Complete();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">internal</span> <span style="color: blue">void</span> Fail(<span style="color: #2b91af">Exception</span> exception)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span>.exception = exception;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Complete();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /><br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">private</span> <span style="color: blue">void</span> Complete()<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>IsCompleted = <span style="color: blue">true</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncWaitHandler.Set();<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">internal</span> <span style="color: blue">void</span> CheckResult()<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (exception != <span style="color: blue">null</span>)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">throw</span> exception;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}</span></p> <h1>Usage<o:p></o:p></h1> <p class="MsoNormal">Now that the implementation is done, it is time to take a look how we would use this new base class:<o:p></o:p></p> <p class="MsoNormal">Imagine an HttpHandler that will asynchronously read in a big movie file, e.g. in 1mb chunks and sends each chunk to the client asynchronously:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">BigVideoHandler</span> : <span style="color: #2b91af">ObservableHttpHandler<br /></span></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">override</span> <span style="color: #2b91af">IObservable</span>&lt;System.<span style="color: #2b91af">Unit</span>&gt; ProcessRequestAsObservable(<span style="color: #2b91af">HttpContext</span> context)<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> fs = <span style="color: blue">new</span> <span style="color: #2b91af">FileStream</span>(<span style="color: #a31515">@"d:\videos\video1.wmv"</span>, <span style="color: #2b91af">FileMode</span>.Open,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">FileAccess</span>.Read, <span style="color: #2b91af">FileShare</span>.Read, 2 &lt;&lt; 19, <span style="color: blue">true</span>);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>context.Response.ContentType = <span style="color: #a31515">"video/x-ms-wmv"</span>;<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> fs.AsyncRead(2 &lt;&lt; 19).WriteToStream(context.Response.OutputStream);<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br /></span><span style="font-family: consolas; mso-bidi-font-size: 11.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p class="MsoNormal"><b style="mso-bidi-font-weight: normal"><i style="mso-bidi-font-style: normal"></i></b>&nbsp;</p> <p class="MsoNormal"><b style="mso-bidi-font-weight: normal"><i style="mso-bidi-font-style: normal">NOTE: </i></b><i style="mso-bidi-font-style: normal">To use this HTTP Handler, it needs to be registered with the webserver. As this is different per webserver, please read <a href="https://msdn.microsoft.com/en-us/library/46c5ddfy(v=VS.100).aspx">this MSDN article</a> on how to do so.</i></p> <p class="MsoNormal"><i style="mso-bidi-font-style: normal"><o:p></o:p></i>&nbsp;</p> <p class="MsoNormal">Even though many asynchronous operations are going on here, the code still looks very concise. The code inside ProcessRequestAsObservable can use any IObservable implementation and any of the Rx operators to orchestrate many asynchronous operations.<o:p></o:p></p> <h1>What’s next<o:p></o:p></h1> <p class="MsoNormal">The HttpHandler pattern is very powerful; it can be used to represent nearly any kind of HTTP request. As it is very low on the stack though, you’ll have to do a lot of manual work. Next in these series we’ll take a look how Rx can help out asynchronous programming in ASP.NET MVC.<o:p></o:p></p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p>]]></content:encoded>
    </item>
    <item>
      <title>Rx on the server, part 4 of n: Buffering output to a stream</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/rx-on-the-server-part-4-of-n-buffering-output-to-a-stream</link>
      <pubDate>Mon, 30 Aug 2010 10:27:11 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/08/30/rx-on-the-server-part-4-of-n-buffering-output-to-a-stream/</guid>
      <description><![CDATA[Previously in these series we saw: &nbsp;   Reading a stream asynchronously  Reading strings...]]></description>
      <content:encoded><![CDATA[<p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">Previously in these series we saw:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"></span>&nbsp;</p> <ul> <li> <div class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx" target="_blank"><span style="color: #0066dd">Reading a stream asynchronously</span></a></span><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"></span></div></li> <li> <div class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/26/rx-on-the-server-part-2-of-n-asynchronous-streamreader.aspx" target="_blank"><span style="color: #0066dd">Reading strings asynchronously, line by line</span></a></span></div></li> <li> <div class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><a href="https://blogs.msdn.com/b/jeffva/archive/2010/08/20/rx-on-the-server-part-3-of-n-writing-an-observable-to-a-stream.aspx"><span style="mso-fareast-font-family: 'Times New Roman'">Writing an observable to a stream</span></a></span></div></li></ul> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><?xml:namespace prefix = o /><o:p></o:p></span>&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">The last post finished with a warning regarding sending to many small chunks of data to the stream asynchronously. <o:p></o:p></span></p> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">In this post we’ll take a look at avoiding that problem by buffering the stream until a minimum size has been reached.<o:p></o:p></span></p> <h2>Signature &amp; Pattern<o:p></o:p></h2> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">As our WriteToStream method expects a IObservable&lt;byte[]&gt; as its input, our transformation is going to go from IObservable&lt;byte[]&gt; to IObservable&lt;byte[]&gt;:</span></p> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"></span><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">&nbsp;</span></p><o:p></o:p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>public</span><span style="font-family: consolas; font-size: 9pt"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">byte</span>[]&gt; MinimumBuffer(<span style="color: blue">this</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">byte</span>[]&gt; source, <o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">int</span> bufferSize)</span></p> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"></span>&nbsp;</p> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">We’re going to be working on an existing observable and produce a new observable out of that. So this is a good fit for the Observable.CreateWithDisposable pattern:</span></p> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"></span><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">&nbsp;</span></p><o:p></o:p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>return</span><span style="font-family: consolas; font-size: 9pt"> <span style="color: #2b91af">Observable</span>.CreateWithDisposable&lt;<span style="color: blue">byte</span>[]&gt;(observer =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>…<span style="mso-spacerun: yes">&nbsp; </span><br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p> <h2>Requirements<o:p></o:p></h2> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">Let’s look at the task at hand, there are a couple of things we need to do:</span></p> <ul> <li><font size="2">Subscribe to the original observable </font></li> <li><font size="2">Handle OnNext messages </font></li> </ul><ul> <li><font size="2">Add the message to a buffer</font></li> <li><font size="2">Fire out a new array based on the content of the buffer when buffer becomes bigger than bufferSize</font></li> <li><font size="2">Clear the buffer</font></li></ul> <ul><li><font size="2">Send through OnError messages immediately</font></li> <li><font size="2">Complete the stream, sending out any remaining data in the buffer on an OnCompleted message.</font></li> <li><font size="2">Return a disposable object that will unsubscribe the original subscription.</font></li></ul> <h2>Implementation<o:p></o:p></h2> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">As we need a buffer that can be accessed through out the subscription, we begin our observable.CreateWithDisposable body with allocating a list to hold that buffer:</span></p> <p style="margin-top: 12pt" class="MsoNormal"><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"></span><span style="line-height: 115%; font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">&nbsp;</span></p><o:p></o:p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> data = <span style="color: blue">new</span> <span style="color: #2b91af">List</span>&lt;<span style="color: blue">byte</span>&gt;();<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 15.5pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-size: 9pt; mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin">Next, we’re going to subscribe to the original stream. As that is the only subscription we’re going to manage, we’ll return the disposable object from that subscription as the object maintaining the subscription to our output stream:<br style="mso-special-character: line-break" /><br style="mso-special-character: line-break" /></span><span style="font-family: consolas; font-size: 15.5pt"><o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;</span><span style="mso-spacerun: yes">&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span><span style="color: blue">return</span> source.Subscribe(value =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>…<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>error=&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>…<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>() =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>…<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: white; mso-background-themecolor: background1; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Now it is time to fill in the details of the subscription.<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">First we’ll tackle the OnNext messages:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">&nbsp;</span></p><o:p></o:p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>data.AddRange(value);<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (data.Count &gt; bufferSize)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnNext(data.ToArray());<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>data.Clear();<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p><span style="line-height: 115%; font-size: 9pt"> <p class="MsoNormal"><br />OnError will be straightforward: As we want to maintain abort semantics, we’ll send through any exception from the source stream immediately:</p> <p class="MsoNormal"></p></span>&nbsp; <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; background: #eeece1; font-size: 9pt; mso-shading-themecolor: background2"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observer.OnError(error);<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">This statement can be reduced to a lambda expression and even further to a method group, which we’ll see in the final code.</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p></o:p></span>&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Once we get an OnCompleted message, we could be in the situation that the buffer still contains data, but hasn’t reached the boundary of bufferSize.</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><br />In that case, we should empty the buffer before sending out OnCompleted to our subscribers:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">&nbsp;</span></p><o:p></o:p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>if</span><span style="font-family: consolas; font-size: 9pt"> (data.Count &gt; 0)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observer.OnNext(data.ToArray());<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observer.OnCompleted();<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <h2>Final Code<o:p></o:p></h2> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">And with that, we have the full implementation of our buffering operator:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">&nbsp;</span></p><o:p></o:p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">byte</span>[]&gt; MinimumBuffer(<span style="color: blue">this</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">byte</span>[]&gt; source,<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span><span style="color: blue">int</span> bufferSize)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: #2b91af">Observable</span>.CreateWithDisposable&lt;<span style="color: blue">byte</span>[]&gt;(observer =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> data = <span style="color: blue">new</span> <span style="color: #2b91af">List</span>&lt;<span style="color: blue">byte</span>&gt;();<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> source.Subscribe(value =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>data.AddRange(value);<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (data.Count &gt; bufferSize)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnNext(data.ToArray());<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>data.Clear();<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnError,<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>() =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp; </span><span style="color: blue">if</span> (data.Count &gt; 0)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnNext(data.ToArray());<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnCompleted();<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p><span style="line-height: 115%; font-size: 9pt"> <p class="MsoNormal"><br />We can now use this operator to avoid performance issues when writing out our observable to a stream:</p> <p class="MsoNormal">&nbsp;</p><o:p></o:p></span> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>source.MinimumBuffer(2 &lt;&lt; 16).WriteToStream(stream);<o:p></o:p></span></p> <h2>What’s next?<o:p></o:p></h2> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">We’ve spent quite some time so far in these series on talking about Streams.<br /> Next we’ll take a look at how we could use these stream operations from ASP.NET. <br />We’ll try to plug Rx into the IHttpAsyncHandler mechanism and use our stream operators from within that pattern.<o:p></o:p></span></p>]]></content:encoded>
    </item>
    <item>
      <title>Testing Rx</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/testing-rx</link>
      <pubDate>Fri, 27 Aug 2010 14:37:28 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/08/27/testing-rx/</guid>
      <description><![CDATA[In this Channel9 video, Wes and me explain the new testing functionality that now ships as part of...]]></description>
      <content:encoded><![CDATA[<p style="line-height: 13.5pt; background: white"><span style="font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en" lang="EN">In <a href="https://channel9.msdn.com/shows/Going+Deep/Wes-Dyer-and-Jeffrey-Van-Gogh-Inside-Rx-Virtual-Time/">this Channel9 video</a>, Wes and me explain the new testing functionality that <a href="https://blogs.msdn.com/b/rxteam/archive/2010/08/27/release-notes.aspx">now ships as part of Rx</a>.<?xml:namespace prefix = o /><o:p></o:p></span></p> <p style="line-height: 13.5pt; background: white"><span style="font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en" lang="EN">As the video goes into great detail on why you’d want to test Rx this way, I won’t go into details here. However as the video briefly touches on a lot of different subjects, here is a sample to get you started writing tests using this functionality.<o:p></o:p></span></p> <p style="line-height: 13.5pt; background: white"><span style="font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en" lang="EN">First we’re going to create a base class that will provide some helpers to our test:<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 15.5pt"><span style="mso-spacerun: yes">&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: blue; font-size: 9pt">public</span><span style="font-family: consolas; font-size: 9pt"> <span style="color: blue">abstract</span> <span style="color: blue">class</span> <span style="color: #2b91af">Test<o:p></o:p></span></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">Recorded</span>&lt;<span style="color: #2b91af">Notification</span>&lt;T&gt;&gt; OnNext&lt;T&gt;(<span style="color: blue">long</span> ticks, T value)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">Recorded</span>&lt;<span style="color: #2b91af">Notification</span>&lt;T&gt;&gt;(ticks, <span style="color: blue">new</span> <span style="color: #2b91af">Notification</span>&lt;T&gt;.<span style="color: #2b91af">OnNext</span>(value));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">Recorded</span>&lt;<span style="color: #2b91af">Notification</span>&lt;T&gt;&gt; OnCompleted&lt;T&gt;(<span style="color: blue">long</span> ticks)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">Recorded</span>&lt;<span style="color: #2b91af">Notification</span>&lt;T&gt;&gt;(ticks, <span style="color: blue">new</span> <span style="color: #2b91af">Notification</span>&lt;T&gt;.<span style="color: #2b91af">OnCompleted</span>());<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">Recorded</span>&lt;<span style="color: #2b91af">Notification</span>&lt;T&gt;&gt; OnError&lt;T&gt;(<span style="color: blue">long</span> ticks, <span style="color: #2b91af">Exception</span> exception)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">Recorded</span>&lt;<span style="color: #2b91af">Notification</span>&lt;T&gt;&gt;(ticks,<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span><span style="color: blue">new</span> <span style="color: #2b91af">Notification</span>&lt;T&gt;.<span style="color: #2b91af">OnError</span>(exception));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">Subscription</span> Subscribe(<span style="color: blue">long</span> start, <span style="color: blue">long</span> end)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">Subscription</span>(start, end);<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">Subscription</span> Subscribe(<span style="color: blue">long</span> start)<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">Subscription</span>(start);<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">Next we’re going to write a test to test the behavior of the Select operator. We’re using the Visual Studio Test Framework here, but it really can be done in any framework.<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">Here is the skeleton code of our test:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p></o:p></span>&nbsp;</p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>[<span style="color: #2b91af">TestClass</span>]<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">SelectTest</span> : <span style="color: #2b91af">Test</span><o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[<span style="color: #2b91af">TestMethod</span>]<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">void</span> Select_Complete()<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 15.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">Let’s start filling in the blanks:<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">First we’ll create a test scheduler:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p></o:p></span>&nbsp;</p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>var</span><span style="font-family: consolas; font-size: 9pt"> scheduler = <span style="color: blue">new</span> <span style="color: #2b91af">TestScheduler</span>();<o:p></o:p></span></p><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"> <p class="MsoNormal"><br />Next we need an observable that our Select operator can operate on:</p> <p class="MsoNormal"><o:p></o:p></p></span>&nbsp; <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>var</span><span style="font-family: consolas; font-size: 9pt"> xs = scheduler.CreateHotObservable(<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(180, 1),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(210, 2),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(240, 3),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(290, 4),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(350, 5),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnCompleted&lt;<span style="color: blue">int</span>&gt;(400),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(410, -1),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnCompleted&lt;<span style="color: blue">int</span>&gt;(420),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnError&lt;<span style="color: blue">int</span>&gt;(430, <span style="color: blue">new</span> <span style="color: #2b91af">MockException</span>(-1)));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 15.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">Notice that this observable doesn’t follow the contract of Rx, as it produces more messages after the first OnCompleted. This is ok as we want to test that the Select operator still behaves correctly in this case.<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">Next we want to run the Select operator over this observable. </span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"></span>&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">The test scheduler code has a set of details to make our live easier:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"></span>&nbsp;</p> <ul> <li> <div class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"></span><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">execute the code creating the observable at virtual time 100</span></div></li> <li> <div class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"></span><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">subscribe to the resulting observable at virtual time 200</span></div></li> <li> <div class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"></span><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">unsubscribe from the subscription at virtual time 1000</span></div></li></ul> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p></o:p></span>&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">These are merely defaults, you’re free to change these around, but they have worked out well in most cases for our testing.</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p></o:p></span>&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN">So with this information, we tell the test scheduler what to do to create the observable and run the test:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p></o:p></span>&nbsp;</p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>var</span><span style="font-family: consolas; font-size: 9pt"> results = scheduler.Run(() =&gt; xs.Select(x =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoked++;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> x + 1;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;</span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}));<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-family: 'Arial','sans-serif'; color: #333333; font-size: 9pt; mso-ansi-language: en; mso-fareast-font-family: 'Times New Roman'" lang="EN"><o:p>&nbsp;</o:p></span></p> <p>In this test, we side effect inside the select, to ensure that it gets invoked exactly as many times as we expect next to this we increment each value coming through by one, to ensure that the select operator is indeed doing the job it’s supposed to do. <p>Next we need to make sure that the resulting observable contained exactly the values we expected at exactly the right virtual time we expected.  <p>The Run method helps us out here as it gives us back an IEnumerable&lt;Recorded&lt;Notification&lt;int&gt;&gt;.  <p>With the help of the AssertEqual extension method, we can verify the results. <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>results.AssertEqual(<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(210, 3),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(240, 4),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(290, 5),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(350, 6),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnCompleted&lt;<span style="color: blue">int</span>&gt;(400));<o:p></o:p></span></p><span style="line-height: 115%; font-size: 9pt"> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">As you can see a lot fewer values than our input, this is due to the following reasons:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p></o:p></span>&nbsp;</p> <ul> <li> <div class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Any message sent out on the hot observable before subscription time (200) will be missed</span></div></li> <li> <div class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Any message sent out after the first OnCompleted or OnError will be ignored <o:p></o:p></span></div></li></ul> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Another thing we’d like to check is that the Select operator is as strict as possible in its subscription to the underlying observable. </span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"></span>&nbsp;</p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Meaning it subscribes only once, as soon as it is needed and unsubscribes as soon as it is no longer needed:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p></o:p></span>&nbsp;</p></span> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 15.5pt"><span style="mso-spacerun: yes">&nbsp;</span></span><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp; </span>xs.Subscriptions.AssertEqual(Subscribe(200, 400));<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Finally we check if the Select operator has been called exactly as frequent as we’d expected:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p></o:p></span>&nbsp;</p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: #2b91af; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>Assert</span><span style="font-family: consolas; font-size: 9pt">.AreEqual(4, invoked);<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt">Our final test code looks as follows:</span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p></o:p></span>&nbsp;</p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>[<span style="color: #2b91af">TestClass</span>]<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">SelectTest</span> : <span style="color: #2b91af">Test</span><o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>[<span style="color: #2b91af">TestMethod</span>]<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: blue">void</span> Select_Complete()<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> scheduler = <span style="color: blue">new</span> <span style="color: #2b91af">TestScheduler</span>();<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> invoked = 0;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> xs = scheduler.CreateHotObservable(<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(180, 1),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(210, 2),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(240, 3),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(290, 4),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(350, 5),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnCompleted&lt;<span style="color: blue">int</span>&gt;(400),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(410, -1),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnCompleted&lt;<span style="color: blue">int</span>&gt;(420),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnError&lt;<span style="color: blue">int</span>&gt;(430, <span style="color: blue">new</span> <span style="color: #2b91af">MockException</span>(-1)));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> results = scheduler.Run(() =&gt; xs.Select(x =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>invoked++;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> x + 1;<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>results.AssertEqual(<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(210, 3),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(240, 4),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(290, 5),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnNext(350, 6),<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>OnCompleted&lt;<span style="color: blue">int</span>&gt;(400));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>xs.Subscriptions.AssertEqual(<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Subscribe(200, 400));<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">Assert</span>.AreEqual(4, invoked);<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 9pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p class="MsoNormal"><span style="line-height: 115%; font-size: 9pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal">We have just implemented our first Rx test. It is the Hello World equivalent for Rx testing. This operator doesn’t involve a lot of complicated scheduling, but it shows all the required basics for using this kind of testing on more complicated scenarios.</p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">Let us know what you think, if anything is missing or can be simplified. As always, feedback is most welcome <a href="https://social.msdn.microsoft.com/Forums/en-US/rx/threads" target="_blank">at our forum</a>.</p></p></p></p></p>]]></content:encoded>
    </item>
    <item>
      <title>Rx on the server, part 3 of n: Writing an observable to a stream</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/rx-on-the-server-part-3-of-n-writing-an-observable-to-a-stream</link>
      <pubDate>Fri, 20 Aug 2010 15:42:27 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/08/20/rx-on-the-server-part-3-of-n-writing-an-observable-to-a-stream/</guid>
      <description><![CDATA[Previously in these series we saw:   Reading a stream asynchronously  Reading strings...]]></description>
      <content:encoded><![CDATA[<p class="MsoNormal"><?xml:namespace prefix = o /><o:p>Previously in these series we saw:</o:p></p> <ul> <li> <div class="MsoNormal"><o:p><a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx" target="_blank">Reading a stream asynchronously</a></o:p></div></li> <li> <div class="MsoNormal"><o:p><a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/26/rx-on-the-server-part-2-of-n-asynchronous-streamreader.aspx" target="_blank">Reading strings asynchronously, line by line</a></o:p></div></li></ul> <p class="MsoNormal">Next, I would like us to take a look at writing an observable to a stream asynchronously.<o:p></o:p></p> <h2>Requirements<o:p></o:p></h2> <p class="MsoNormal">When we write an observable to a stream, there are several issues we have to deal with:</p> <blockquote> <p class="MsoNormal"><span style="mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: ignore">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>We want to write all data in the observable to the file.</p> <p class="MsoNormal"><span style="mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: ignore">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>These values should be written to the file in order.</p> <p class="MsoNormal"><span style="mso-bidi-font-family: calibri; mso-bidi-theme-font: minor-latin"><span style="mso-list: ignore">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>We want to be notified once the whole file has been written.</p></blockquote> <p class="MsoNormal">From 1 and 3 we can derive the signature for our method:</p> <p class="MsoNormal">&nbsp;</p><o:p></o:p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue">public</span><span style="font-family: consolas"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: #2b91af">Unit</span>&gt; WriteToStream(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">byte</span>[]&gt; source, <span style="color: #2b91af">Stream</span> stream)</span></p> <p class="MsoNormal">&nbsp;</p> <h2>Data Corruption</h2> <p class="MsoNormal">Point 2 is interesting. Given that we are in an asynchronous world, we have to be very careful of potential data corruption. We want to make sure that if one piece of data is in process of being written to a file, the next piece of data comes in doesn’t corrupt the first write.<o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">When doing the research for this post, I initially wrote a Drain operator that would avoid these kinds of issues. </p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p class="MsoNormal">I was almost ready to post about this operator, when I found something interesting that was deeply buried inside the MSDN documentation for <a href="https://msdn.microsoft.com/en-us/library/system.io.stream.beginwrite.aspx">BeginWrite</a>:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="margin-left: 0.5in" class="MsoNormal"><i style="mso-bidi-font-style: normal">“</i><span class="apple-style-span"><i style="mso-bidi-font-style: normal"><span style="line-height: 115%; font-family: 'Segoe UI','sans-serif'; color: black; font-size: 10pt">The current position in the stream is updated when you issue the asynchronous read or write, not when the I/O operation completes. Multiple simultaneous asynchronous requests render the request completion order uncertain.</span>”</i></span></p> <p style="margin-left: 0.5in" class="MsoNormal"><span class="apple-style-span"><i style="mso-bidi-font-style: normal"><o:p></o:p></i></span></p> <p class="MsoNormal">In order words, the position of the stream is updated synchronously in the call to BeginWrite. This means that a chunk in the file of the exact size of your data is reserved for each call to BeginWrite. This will ensure that no data corruptions happen because of simultaneous writes.</p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">Because of the following two guarantees Rx gives us:</p> <blockquote> <p class="MsoNormal"><span style="font-family: symbol; mso-bidi-font-family: symbol; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>The grammar is OnNext* (OnCompleted| OnError)? </p> <p class="MsoNormal"><span style="font-family: symbol; mso-bidi-font-family: symbol; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>All calls to IObserver are serialized.</p></blockquote> <p class="MsoNormal">We can safely call BeginWrite any time a message comes in.<o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">The second sentence talks about the completion order. The uncertain order is not important for us. We are only interesting in knowing that all operations have completed.<o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <h2>Out with the Drain operator</h2> <p class="MsoNormal">Given these new facts, we can throw away the Drain operator. I’ll keep the code around and will blog about in the future. As I’m sure there are scenarios were we will need it.<o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">So let’s see how to code up the solution without Drain.<o:p></o:p></p> <h2>BeginWrite<o:p></o:p></h2> <p class="MsoNormal">First we’re going to need an observable version of BeginWrite:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue">var</span><span style="font-family: consolas"> asyncWrite = Observable.FromAsyncPattern&lt;<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">byte</span>[], <span style="color: blue">int</span>, <span style="color: blue">int</span>&gt;(stream.BeginWrite, stream.EndWrite);<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Next we want to call asyncWrite for each block of data that comes in to our source observable.<o:p></o:p></p> <h2>SelectMany<o:p></o:p></h2> <p class="MsoNormal">The preferred way to create new asynchronous operations from an observable is to use the SelectMany operator. (SelectMany has other fine uses, but this is a common one). <o:p></o:p></p> <p class="MsoNormal"><i style="mso-bidi-font-style: normal"></i>&nbsp;</p> <p class="MsoNormal"><i style="mso-bidi-font-style: normal">You can skip this section if you’re already familiar with SelectMany.<o:p></o:p></i></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">The SelectMany operator takes a selector function argument. This selector function gets called for every value sent through the source observable. The selector should return an observable for each value. <o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">The SelectMany operator merges results from all observables produced by the selector function into a single observable that is returned to the user. </p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p class="MsoNormal">The observable returned from SelectMany fires OnCompleted once all observables produced by the selector have completed.<o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">The returned observable fires OnError in the following cases:</p> <blockquote> <p class="MsoNormal"><span style="font-family: symbol; mso-bidi-font-family: symbol; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>An error occurred in the source stream.</p> <p class="MsoNormal"><span style="font-family: symbol; mso-bidi-font-family: symbol; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>An exception was thrown by the selector function.</p> <p class="MsoNormal"><span style="font-family: symbol; mso-bidi-font-family: symbol; mso-fareast-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>An error occurred in any of the produced observables.<o:p></o:p></p></blockquote> <h2>WriteToStream Implementation<o:p></o:p></h2> <p class="MsoNormal">We’ll use SelectMany in our WriteToStream operator as follows:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas">source.SelectMany(data =&gt; asyncWrite(data, 0, data.Length))<o:p></o:p></span></p> <p class="MsoNormal"><br />We now have an IObservable&lt;Unit&gt; that will fire an OnNext message with Unit for each separate write. After which, the observable will fire OnCompleted to signal that all data has been written.<o:p></o:p></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">To clean up our operator, we want to get rid of the unnecessary Unit messages coming through. We want to make sure though that we still get notified of either completion or errors that might have happened. We remove all OnNext messages by using the Where operator that filters every single OnNext message:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue">return</span><span style="font-family: consolas"> source.SelectMany(data =&gt; asyncWrite(data, 0, data.Length))<br />&nbsp;&nbsp;&nbsp; .Where(_ =&gt; <span style="color: blue">false</span>);<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">The final version of our operator looks like this:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue">public</span><span style="font-family: consolas"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: #2b91af">Unit</span>&gt; WriteToStream(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">byte</span>[]&gt; source, <span style="color: #2b91af">Stream</span> stream)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> asyncWrite = <span style="color: #2b91af">Observable</span>.FromAsyncPattern&lt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>byte</span><span style="font-family: consolas">[], <span style="color: blue">int</span>, <span style="color: blue">int</span>&gt;(stream.BeginWrite, stream.EndWrite);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> source.SelectMany(data =&gt; <br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>asyncWrite(data, 0, data.Length)).Where(_ =&gt; <span style="color: blue">false</span>);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas">}<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p><strong>WARNING</strong>: <font color="#ff0000"><strong>As this operator starts writing any piece of data it receives immediately, this can lead to performance issues when writing many small chunks of data. <br /></strong><br /></font>Next in these series, we’ll look at how we can create a buffer to only save out bigger chunks of data to avoid this potential performance issue.<o:p></o:p></p>]]></content:encoded>
    </item>
    <item>
      <title>Rx on the server, part 2 of n: Asynchronous StreamReader</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/rx-on-the-server-part-2-of-n-asynchronous-streamreader</link>
      <pubDate>Mon, 26 Jul 2010 10:26:10 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/07/26/rx-on-the-server-part-2-of-n-asynchronous-streamreader/</guid>
      <description><![CDATA[In part 1 of these series, we talked about how to read a stream asynchronously. This resulted in an...]]></description>
      <content:encoded><![CDATA[<p class="MsoNormal">In <a href="https://blogs.msdn.com/b/jeffva/archive/2010/07/23/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading.aspx" target="_blank"><span style="color: blue">part 1</span></a> of these series, we talked about how to read a stream asynchronously. This resulted in an operator returning IObservable&lt;byte[]&gt;. This type can be useful in many scenarios, e.g. you’re processing a large image. However there are plenty of scenarios you want to retrieve the content of the file in a more descriptive way. E.g. imagine parsing a huge CSV file. In that case we’d like to see a type like IObservable&lt;string&gt; where each OnNext call represents a whole line in the file. In this part of the series, we’ll look into how we can create an operator that fits this signature.<?xml:namespace prefix = o /><o:p></o:p></p> <h2>StreamReader<o:p></o:p></h2> <p class="MsoNormal">The .NET BCL provides a synchronous way of writing the pattern we described above through the <a href="https://msdn.microsoft.com/en-us/library/system.io.streamreader_members.aspx" target="_blank"><span style="color: blue">StreamReader</span></a> class, unfortunately this class doesn’t provide asynchronous versions of methods like ReadLine. So we’ll have to cook up something ourselves. <o:p></o:p></p> <p class="MsoNormal">That doesn’t mean of course, we can’t learn from what the implementation of StreamReader. So we’re off to the <a href="https://referencesource.microsoft.com/netframework.aspx" target="_blank"><span style="color: blue">reference source</span></a> to take a look at DEVDIV_TFS\Dev10\Releases\RTMRel\ndp\clr\src\BCL\System\IO\StreamReader.cs\1305376\StreamReader.cs. Here we find a couple of interesting things about StreamReader/ReadLine:</p> <p class="MsoNormal">&nbsp;</p> <ul> <li> <div class="MsoNormal">It uses a buffer that reads from the underlying stream</div></li> <li> <div class="MsoNormal">It uses the Encoding class to go from byte[] to strings</div></li> <li> <div class="MsoNormal">As encoding can span multiple buffer reads, a lot of logic happens here to avoid issues around that.</div></li> <li> <div class="MsoNormal">When ReadLine is called, it walks through this buffer to find the next new line (\r, \r\n or \n). Whenever it finds that or finds the end of the file, it builds a string and returns the value.</div></li></ul> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p class="MsoNormal">Let’s try to convert this to the async pattern. We’re going to ignore the encoding part for now as that would clutter the sample and we’re going to assume ASCII encoding.</p> <p class="MsoNormal">&nbsp;</p> <ul> <li> <div class="MsoNormal">We’ll use the AsyncRead method from our previous sample to push asynchronous reads of byte[] to us.</div></li> <li> <div class="MsoNormal">We’ll return an IObservable&lt;string&gt; that will be pushed lines in the file.</div></li> <li> <div class="MsoNormal">We’ll build a buffer of characters until we hit a new line or the end of the file</div></li> <li> <div class="MsoNormal">Once we hit that condition, we fire out a call to OnNext to push out the line we build up. After which we’ll clear the buffer.</div></li></ul> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p class="MsoNormal">So let’s get started. First we define the signature of this method:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">public</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">string</span>&gt; AsyncReadLines(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span> <span style="color: #2b91af">Stream</span> stream, <span style="color: blue">int</span> bufferSize)<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Next we’re going to write a buffering IObservable that works based on the original IObservable from AsyncRead. Often, these kind of operations could be done by doing a transformation on the AsyncRead observable e.g. with the Scan operator. However, as we also want to do some work when the source observable completes (at the end of the file) it is best to write a custom implementation using Observable.CreateWithDisposable.<o:p></o:p></p> <h2>Observable.CreateWithDisposable &amp; Observable.Create<o:p></o:p></h2> <p class="MsoNormal">These methods are convenient helpers to allow you to write concrete implementations of IObservable without having to deal with a lot of the clutter. The signature of Observable.CreateWithDisposable is the following:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">public</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;TSource&gt; CreateWithDisposable&lt;TSource&gt;(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">Func</span>&lt;<span style="color: #2b91af">IObserver</span>&lt;TSource&gt;, <span style="color: #2b91af">IDisposable</span>&gt; subscribe)<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Now, if you look at the IObservable interface definition:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">public</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> <span style="color: blue">interface</span> <span style="color: #2b91af">IObservable</span>&lt;TSource&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: #2b91af; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>IDisposable</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> Subscribe(<span style="color: #2b91af">IObserver</span>&lt;TSource&gt; observer);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">}<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal">You’ll see that the signature of the Func&lt;&gt; passed into CreateWithDisposable looks a lot alike the signature of the Subscribe method of the IObservable interface. Well that’s completely correct. Observable.CreateWithDisposable is a trick that we’re using in Rx to work around the fact that C# doesn’t support anonymous inner-types. In languages that support anonymous inner types, you would write something like this:<o:p></o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><o:p>&nbsp;</o:p></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><br /><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">public</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">string</span>&gt; AsyncReadLines(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span> <span style="color: #2b91af">Stream</span> stream, <span style="color: blue">int</span> bufferSize)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: blue">new</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">string</span>&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">public</span> <span style="color: #2b91af">IDisposable </span>Subscribe(<span style="color: #2b91af">IObserver</span>&lt;<span style="color: blue">string</span>&gt; observer)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><o:p>&nbsp;</o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal">Working around the lack of anonymous inner-types, we can now write something like this:</p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">public</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">string</span>&gt; AsyncReadLines(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span> <span style="color: #2b91af">Stream</span> stream, <span style="color: blue">int</span> bufferSize)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: #2b91af">Observable</span>.CreateWithDisposable&lt;<span style="color: blue">string</span>&gt;(observer =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">}<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><o:p>&nbsp;</o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal">Next to providing a convenient way of writing Observable implementations inline, the Observable.CreateWithDisposable operator provides another handy feature that otherwise would require a lot of plumbing: It wraps any observer passed into Subscribe in an observer that does two nifty things:<o:p></o:p></p> <p style="line-height: normal; text-indent: -0.25in; margin: 0in 0in 0pt 38.25pt; mso-list: l0 level1 lfo3; mso-layout-grid-align: none; mso-add-space: auto" class="MsoListParagraphCxSpFirst"><span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>When the Observable stream is done (either by firing OnError or Oncompleted, it automatically disposes the subscription to the Observable, cleaning up any state as soon as possible.<o:p></o:p></p> <p style="line-height: normal; text-indent: -0.25in; margin: 0in 0in 0pt 38.25pt; mso-list: l0 level1 lfo3; mso-layout-grid-align: none; mso-add-space: auto" class="MsoListParagraphCxSpLast"><span style="font-family: symbol; mso-fareast-font-family: symbol; mso-bidi-font-family: symbol"><span style="mso-list: ignore">·<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>It ensures that once OnError or OnCompleted is called once, no more messages are sent through to any of the OnNext, OnError or OnCompleted messages, to ensure the Rx contract of OnNext* (OnError|OnCompleted)?<o:p></o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><o:p>&nbsp;</o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal">Observable.Create is almost the same as Observable.CreateWithDisposable. The only difference is that the subscribe Func&lt;&gt; returns an Action instead of an IDisposable. The idea is the same here, you don’t have to create an implementation of IDisposable, but use an action as your anonymous inner type version of IDisposable.Dispose.<o:p></o:p></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><o:p>&nbsp;</o:p></p> <h2>AsyncReadLines Implementation<o:p></o:p></h2> <p class="MsoNormal">Ok, let’s get back to the problem at hand. We’ve got the wireframe for our method; now let’s look at the details.<o:p></o:p></p> <p class="MsoNormal">First we’re going to start with calling our AsyncRead method from the previous blog entry:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">var</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> blocks = AsyncRead(stream, bufferSize);<o:p></o:p></span></p> <p class="MsoNormal"><br />Now this still works on byte[] and we said we wanted to work in ASCII, so let’s convert that:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">var</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> blocks = AsyncRead(stream, bufferSize)<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>.Select(block=&gt;<span style="color: #2b91af">Encoding</span>.ASCII.GetString(block));<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Next we want to do something with the data inside the source IObservable. The only way to get to that data is to subscribe to the stream:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">var</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> subscription = blocks.Subscribe(data =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>exception =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>() =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p class="MsoNormal">&nbsp;</p> <p class="MsoNormal">We’ll also have to make a decision on how the user can unsubscribe the observer they passed to our observable. In this case, when the user unsubscribes from our observable, we need to unsubscribe from the subscription we made ourselves, so we’ll modify the code to return the subscription we received ourselves:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">return</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> blocks.Subscribe(data =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>exception =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>() =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>...<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Now that we’ve hooked up to the source observable, we get a call every time new data is available. This data is presented as a string that potentially contains several lines. So let’s write some code to parse that string. We’re going to walk through the string and look for \r, \r\n or \n tokens. If we find one of those were at the end of a line and we’ll have to take some action. If we’re not at the end of a line, we put the character in a temporary buffer (a StringBuilder).</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">var</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> sb = <span style="color: blue">new</span> <span style="color: #2b91af">StringBuilder</span>();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">for</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> (<span style="color: blue">var</span> i = 0; i &lt; data.Length; i++)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> atEndofLine = <span style="color: blue">false</span>;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> c = data[i];<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (c == <span style="color: #a31515">'\r'</span>)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>atEndofLine = <span style="color: blue">true</span>;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> j = i + 1;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (j &lt; data.Length &amp;&amp; data[j] == <span style="color: #a31515">'\n'</span>)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>i++;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">else</span> <span style="color: blue">if</span> (c == <span style="color: #a31515">'\n'</span>)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>atEndofLine = <span style="color: blue">true</span>;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (atEndofLine)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>produceCurrentLine();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">else</span><o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>sb.Append(c);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">}<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Before we look at what we want to do when we see an end of line (the <span style="line-height: 115%; font-family: consolas; mso-bidi-font-size: 14.0pt">produceCurrentLine</span> call), let’s take a look at what we should do in case of OnError or OnComplete coming through on the source observable.<o:p></o:p></p> <p class="MsoNormal">As Rx likes to maintain abort semantics for exceptions, we’re going to pass any exception that comes in on the source IObservable through right away, so we’ll make any call to OnError pass through to the subscribing observer:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">exception =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observer.OnError(exception);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 14pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal">This can be simplified by converting the statement lambda into a method group:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">observer.OnError<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">For OnCompleted we’ll have to do some more work. Imagine a file that doesn’t have a newline at the end of the file, we still like to send out this string. So when our source signals OnCompleted, we’ll have to do the same work as when we hit a newline character inside our OnNext. So we’re going to share that code. After we’ve produced the current line, we fire OnCompleted.</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">() =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>produceCurrentLine();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observer.OnCompleted();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">});<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal">Now let’s implement produceCurrentLine. We need to get the string out of the buffer, reinitialize the buffer and send the string to onNext:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: #2b91af; mso-bidi-font-size: 14.0pt">Action</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> produceCurrentLine = () =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> text = sb.ToString();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>sb.Length = 0;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>observer.OnNext(text);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">};<o:p></o:p></span></p> <p style="line-height: normal; margin-bottom: 0pt; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; font-size: 14pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal">And with that we have the full implementation of our AsyncReadLines operator:</p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">public</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> <span style="color: blue">static</span> <span style="color: #2b91af">IObservable</span>&lt;<span style="color: blue">string</span>&gt; AsyncReadLines(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">this</span> <span style="color: #2b91af">Stream</span> stream, <span style="color: blue">int</span> bufferSize)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> <span style="color: #2b91af">Observable</span>.CreateWithDisposable&lt;<span style="color: blue">string</span>&gt;(observer =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> sb = <span style="color: blue">new</span> <span style="color: #2b91af">StringBuilder</span>();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> blocks = AsyncRead(stream, bufferSize).Select(<br /><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>block =&gt; <span style="color: #2b91af">Encoding</span>.ASCII.GetString(block));<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af">Action</span> produceCurrentLine = () =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> text = sb.ToString();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>sb.Length = 0;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnNext(text);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>};<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">return</span> blocks.Subscribe(data =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">for</span> (<span style="color: blue">var</span> i = 0; i &lt; data.Length; i++)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> atEndofLine = <span style="color: blue">false</span>;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> c = data[i];<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (c == <span style="color: #a31515">'\r'</span>)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>atEndofLine = <span style="color: blue">true</span>;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">var</span> j = i + 1;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (j &lt; data.Length &amp;&amp; data[j] == <span style="color: #a31515">'\n'</span>)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>i++;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">else</span> <span style="color: blue">if</span> (c == <span style="color: #a31515">'\n'</span>)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>atEndofLine = <span style="color: blue">true</span>;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: blue">if</span> (atEndofLine)<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>produceCurrentLine();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="mso-spacerun: yes">&nbsp;</span><span style="color: blue">else</span><o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>sb.Append(c);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>},<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnError,<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>() =&gt;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>produceCurrentLine();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>observer.OnCompleted();<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span>});<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">}<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal"><o:p>The following program shows how to use this operator:</o:p></p> <p class="MsoNormal"><o:p></o:p>&nbsp;</p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: green; mso-bidi-font-size: 14.0pt">// bufferSize &gt; 64k as per BeginRead spec: <a href="https://msdn.microsoft.com/en-us/library/zxt5ahzw.aspx" target="_blank">https://msdn.microsoft.com/en-us/library/zxt5ahzw.aspx</a></span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">var</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> bufferSize = 2 &lt;&lt; 16;<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: green; mso-bidi-font-size: 14.0pt">// constructor of FileStream that enables asynchronous operations</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; color: blue; mso-bidi-font-size: 14.0pt">var</span><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"> stream = <span style="color: blue">new</span> <span style="color: #2b91af">FileStream</span>(<span style="color: #a31515">@"d:\temp\input.txt"</span>, <span style="color: #2b91af">FileMode</span>.Open, <span style="color: #2b91af">FileAccess</span>.Read, <span style="color: #2b91af">FileShare</span>.Read, bufferSize, <span style="color: blue">true</span>);<o:p></o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt"><o:p>&nbsp;</o:p></span></p> <p style="line-height: normal; margin: 0in 0in 0pt 0.5in; background: #eeece1; mso-background-themecolor: background2; mso-layout-grid-align: none" class="MsoNormal"><span style="font-family: consolas; mso-bidi-font-size: 14.0pt">stream.AsyncReadLines(bufferSize).Run(<span style="color: #2b91af">Console</span>.WriteLine);<o:p></o:p></span></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p> <p class="MsoNormal"><b style="mso-bidi-font-weight: normal">What’s next?<o:p></o:p></b></p> <p class="MsoNormal">In these series, we’ve seen how to asynchronously read from a file. In this post, we learned how to create an operator that buffers data and sends out this buffer in useful chunks. Next we’ll tackle writing to a file asynchronously and see what kind of specific challenges that operation brings.<o:p></o:p></p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p>]]></content:encoded>
    </item>
    <item>
      <title>Rx on the server, part 1 of n: Asynchronous System.IO.Stream reading</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading</link>
      <pubDate>Thu, 22 Jul 2010 17:06:05 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/07/22/rx-on-the-server-part-1-of-n-asynchronous-system-io-stream-reading/</guid>
      <description><![CDATA[As it’s been a long time since I blogged, I figured I owe it to people subscribed to my blog to...]]></description>
      <content:encoded><![CDATA[<p>As it’s been a long time since I blogged, I figured I owe it to people subscribed to my blog to start a nice long series with regular posts. (Also I can’t stand seeing <a href="codebetter.com/blogs/matthew.podwysocki/">Matthew</a> have all the fun :)).</p> <p>There have been many samples showing Rx on the client. In these samples, Rx is often used for UI operations (such as <a href="https://blogs.msdn.com/b/wesdyer/archive/2009/11/18/a-brief-introduction-to-the-reactive-extensions-for-net-rx.aspx" target="_blank">Drag Drop</a>) and/or network requests (e.g. <a href="https://codebetter.com/blogs/matthew.podwysocki/archive/2010/03/15/introduction-to-the-reactive-extensions-for-javascript-wikipedia-lookup.aspx" target="_blank">dictionary suggest</a>). What I haven’t seen much of is samples of using Rx on the server. Well it’s time to change that! </p> <p>These series will focus on scenarios where you could use Rx on the server. I’ll start out with a couple of posts on reading and writing asynchronously from and to System.IO.Stream objects. After that I plan to discuss using Rx for Asynchronous ASP.NET programming, followed by anything else that might come up.. <br /><br />This will be a pretty advanced series, probably at the 300 level. If I go too fast, feel free to post comments or ask questions on the <a href="https://social.msdn.microsoft.com/Forums/en-US/rx/threads" target="_blank">Rx forum</a></p> <p>So with that, let’s jump right into part 1:</p> <h1>Asynchronous System.IO.Stream reading</h1> <p>First of all, why do we care about asynchronous reading? The Wikipedia page on <a href="https://en.wikipedia.org/wiki/Asynchronous_I/O" target="_blank">Asynchonous I/O</a> gives a good description on why: We don’t want to block on slow IO operations. This is something that can be of importance on a client application as well, but in a server application it quickly becomes critical. With hundreds of clients, servers often cannot afford to have a thread blocked on IO.&nbsp; <br /><br />So that’s where Asynchronous I/O comes in. The .NET BCL exposes this pattern through the BeginRead/EndRead &amp; BeginWrite/EndWrite methods. While this provides a more optimal way of dealing with slow I/O from a runtime perspective, it isn’t really an optimal way of writing your code. As each separate asynchronous operation requires a Begin/End pair as well as a set of delegates, you can quickly get into spaghetti code. So let’s take a look if we can improve on this pattern with Rx.</p> <p>In order to give Rx access to the Asynchronous I/O operations, we’re first going to convert the BeginRead/EndRead pattern into a Rx pattern:<span style="font-family: consolas; font-size: medium"><font size="4" face="Consolas"></font></span></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead = </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Observable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.FromAsyncPattern&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[], </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;( <br />&nbsp;&nbsp;&nbsp;&nbsp; stream.BeginRead, stream.EndRead);</span></span></p></blockquote> <p>What does this mean? FromAsyncPattern takes the something that follows the Begin* End* pattern and converts it into a Func&lt;arguments, IObservable&lt;returnvalue&gt;&gt;. When somebody calls this Func&lt;&gt;, the following happens:</p> <ul> <li>the arguments passed in to the returned Func&lt;&gt; are passed into to the Begin* method.  </li><li>Additionally the right steps are taken to hookup the Begin* to a callback that is called once the asynchronous action is completed.  </li><li>The func returns an IObservable&lt;returnvalue&gt;. The concrete implementation of this IObservable&lt;returnvalue&gt; is an AsyncSubject&lt;returnvalue&gt;.  </li><li>Once the callback gets called, the return value of the asynchronous computation is retrieved by calling End*. This value is then sent to the AsyncSubject by calling OnNext &amp; OnCompleted. </li></ul> <p><strong>NOTE: The fact that the concrete implementation of the IObservable returned here is an AsyncSubject, means that this observable is ‘<a href="https://channel9.msdn.com/posts/J.Van.Gogh/Rx-API-in-depth-Hot-and-Cold-observables/" target="_blank"><font color="#ff0000">HOT</font></a>’. The reason for this is that the async operation might have completed before you’re able to subscribe to the IObservable that you get back. Without an AsyncSubject, there could be a race condition in which you would miss the result.</strong></p> <p>In the case of stream.BeginRead &amp; stream.EndRead, the type arguments to FromAsyncPattern are: the first three arguments to <a href="https://msdn.microsoft.com/en-us/library/zxt5ahzw.aspx" target="_blank">BeginRead</a>: array, offset, numBytes, followed by the return value of <a href="https://msdn.microsoft.com/en-us/library/525xt96h.aspx" target="_blank">EndRead</a>: The number of bytes read from the stream, between 0 and the number of bytes you requested.</p> <p>For this case, the return value of FromAsyncPattern will have the following signature: <br />Func&lt;byte[], int,int, IObservable&lt;int&gt;&gt;</p> <p>So let’s see how we can use this new asyncRead function:<span style="font-family: consolas; font-size: medium"><font size="4" face="Consolas">&nbsp;</font></span></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium">// bufferSize &gt; 64k as per BeginRead spec <br /><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium">// </span></span></span><a href="https://msdn.microsoft.com/en-us/library/zxt5ahzw.aspx" target="_blank">https://msdn.microsoft.com/en-us/library/zxt5ahzw.aspx</a><br /></span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bufferSize = 2 &lt;&lt; 16;&nbsp; <br /></span></span><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><br />// constructor of FileStream that enables asynchronous operations <br /></span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium">// </span></span></span><a href="https://msdn.microsoft.com/en-us/library/7db28s3c.aspx" target="_blank">https://msdn.microsoft.com/en-us/library/7db28s3c.aspx</a><br /><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> stream = </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">new</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">FileStream</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">(</span></span><span style="font-family: consolas; color: #a31515; font-size: medium"><span style="font-family: consolas; color: #a31515; font-size: medium"><span style="font-family: consolas; color: #a31515; font-size: medium">@"d:\temp\input.txt"</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">FileMode</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.Open, </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">FileAccess</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.Read, <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">FileShare</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.Read,</span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bufferSize, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">true</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">); </span>&nbsp;</span></span></p> <p><font size="3" face="Consolas"></font></p> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead = </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Observable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.FromAsyncPattern&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[], </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;(stream.BeginRead, <br />&nbsp;&nbsp;&nbsp; stream.EndRead); </span></span><span style="font-family: consolas; font-size: medium"></span></p> <p><font size="3" face="Consolas"></font></p> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> buffer = </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">new</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[bufferSize]; <br /></span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> oiRead = asyncRead(buffer, 0, bufferSize); <br />oiRead.Run(bytesRead =&gt; <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Console</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.WriteLine(</span></span><span style="font-family: consolas; color: #a31515; font-size: medium"><span style="font-family: consolas; color: #a31515; font-size: medium"><span style="font-family: consolas; color: #a31515; font-size: medium">"The program read {0} bytes asynchronously"</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, bytesRead));</span></span></p></blockquote> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">Clearly the beginning of something beautiful :). Although several things don’t look natural yet:</font></span></span></p> <ul> <li><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">The observable contains the amount of bytes read, the data is state maintained outside of the operation (in the buffer).</font></span></span>  </li><li><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">User code will have to deal with partially filled buffers if less bytes were available than the buffer size.</font></span></span>  </li><li><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">The operation only reads once and will need to be repeated if the file is larger than bufferSize or if the stream wasn’t ready to provide all contents of the file</font></span></span> </li></ul> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">let’s try to tackle the first to points first:</font></span></span></p> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">We’ll factor out the code into an extension method on Stream and select in the value of the buffer into the observable:</font></span></span><span style="font-family: consolas; font-size: medium"><font size="4" face="Consolas"></font></span></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">public</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">static</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[]&gt; AsyncRead(</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">this</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Stream</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> stream, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bufferSize) <br />{ <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead = </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Observable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.FromAsyncPattern&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[], </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;( <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">stream.BeginRead, stream.EndRead);<font size="4" face="Consolas"><font size="4" face="Consolas">&nbsp;</font></font></span><font size="4" face="Consolas">&nbsp;</font></span></p> <p></p> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp; var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> buffer = </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">new</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[bufferSize];<font size="4" face="Consolas"><font size="4" face="Consolas">&nbsp;</font></font></span><font size="4" face="Consolas">&nbsp;</font></span></p> <p></p> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp; return</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead(buffer, 0, bufferSize).Select(readBytes =&gt; <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> newBuffer = </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">new</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[readBytes]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Array</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.Copy(buffer, newBuffer, readBytes); <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">return</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> newBuffer; <br />&nbsp;&nbsp;&nbsp; }); <br />}</span></span></p></blockquote><font size="2"></font> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">This small refactoring has made the usage of the code quite a bit cleaner:</font></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span></span></p> <blockquote style="background-color: #cccccc"> <p>stream.AsyncRead(bufferSize).Run(bytes =&gt; DoSomethingWithData(bytes));</p></blockquote> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">Now let’s try to tackle the last issue. We want to keep the signature we created above, however the IObservable&lt;byte[]&gt; should not fire OnNext a single time. It should fire OnNext with as many byte[] instances as it takes to completely read the stream. The reason we want to fire several times, and not once at the end when all data is read in is that we’re potentially dealing with very big files (imagine reading in a 50GB file in 1MB chunks).</font></span></span></p> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">One thing that could come to mind is to to try to use the Repeat operator to accomplish this. That will not work unfortunately as the Repeat operator only work on ‘<a href="https://channel9.msdn.com/posts/J.Van.Gogh/Rx-API-in-depth-Hot-and-Cold-observables/" target="_blank">Cold</a>’ observables. If we were to use repeat on the observable returned by asyncRead, it would indefinately return the value produced by the first call to BeginRead.</font></span></span></p> <p><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><font size="2" face="Arial">So what can we do instead? We want to make repeated calls to asyncRead, retrieving new observables and concatenating as long as the amount of bytes read is greater than 0. We also want to make sure only one asyncRead operation is in flight at a time to maintain ordering. This is a pretty imperative operation that we want to do in an asynchronous fashion. In Rx, the preferred way to do these kind of operations is using the Iterate operator.</font></span></span></p> <h2>The Iterate Operator</h2> <p><font size="2" face="Arial">One of the signatures for the Iterate operator is as follows:</font></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">public static</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;TResult&gt; Iterate&lt;TResult&gt;(</span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Func</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObserver</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;TResult&gt;, </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IEnumerable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">object</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;&gt;&gt; iteratorMethod)</span></span></p></blockquote> <p><font size="2" face="Arial">A </font><font size="2" face="Arial">pretty complex signature. It takes a function that get’s passed in an IObservable&lt;TResult&gt; as an argument, and returns an IEnumerable that yields values of IObservable&lt;object&gt; and somehow turns it into an IObservable&lt;TResult&gt;</font></p> <p><font size="2" face="Arial">The reason for this signature, is to make Rx play nice with the <a href="https://msdn.microsoft.com/en-us/library/65zzykke.aspx" target="_blank">C# Iterator pattern</a>. It allows users to write asynchronous code, returning IObservables while writing code that looks imperative. If you’re unfamiliar with the C# iterator pattern’s normal use case, I suggest you visit the link above first.</font></p> <p><font size="2" face="Arial">The way the C# Iterator pattern does it’s normal job is by taking the user code that looks imperative and wrap it inside out and build&nbsp; a state-machine. The state-machine keeps track of the control-flow and invokes parts of the user code when it hits the right state. Normally a state transition happens when code calling the C# Iterator pattern needs the next value from the IEnumerable (MoveNext). The state-machine invokes a piece of the user code until the next yield return or break. After which control is returned to the code calling the state-machine. </font></p> <p><font size="2" face="Arial">We can use this for Rx as well. In this case, instead of yield returning a value, we yield return the Observable we’re waiting for to complete. The user code will yield control and the Iterator operator will ensure that the user-code gets control back the moment the Observable is complete. As the return is now taken up by our signaling of Observable completion, we need another way to produce values to the outside world. That’s where the IObserver argument comes in. This is our handle to producing values to the outside world.</font></p> <p><font size="2" face="Arial">So let’s see the Iterate operator in action:</font></p> <p><font size="2" face="Arial">As C# currently doesn’t support the Iterator pattern inside lambdas, we’ll have to call out to a helper method first:</font><span style="font-family: consolas; font-size: medium"><font size="4" face="Consolas"></font></span></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">static</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[]&gt; AsyncRead(</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">this</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Stream</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> stream, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bufferSize) <br />{ <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">return</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Observable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.Iterate&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[]&gt;(result =&gt; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AsyncReadHelper(result, stream, bufferSize)); <br />}</span></span></p></blockquote> <p><font size="2" face="Arial">Next we’ll build the skeleton for our helper:</font></p> <blockquote style="background-color: #cccccc"> <p><font size="2" face="Arial"></font><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><br />private</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">static</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IEnumerable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">object</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;&gt; AsyncReadHelper( <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObserver</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[]&gt; result, </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Stream</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> stream, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bufferSize) <br />{ <br /></span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp; var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead = </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Observable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.FromAsyncPattern&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[], </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;( <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream.BeginRead, stream.EndRead); <br /></span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp; var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> buffer = </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">new</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[bufferSize];<font size="4" face="Consolas"><font size="4" face="Consolas">&nbsp;</font></font></span><font size="4" face="Consolas">&nbsp;</font> </span></p> <p></p> <p></p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp; while</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> (</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">true</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">) <br />&nbsp;&nbsp;&nbsp; { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; …</span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> <br />&nbsp;&nbsp;&nbsp; } <br />}</span></span>  <p></p></blockquote> <p><font size="2" face="Arial">What to put inside the while? In order to match the method’s signature, it’ll have to be something like this:</font></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">yield</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">return</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead(buffer, 0, bufferSize);</span></span></p></blockquote> <p><font size="2" face="Arial">This will yield control back to the Iterator operator until the asyncRead completes after which the next line of the method is called.There are however several problems with that: </font></p> <ul> <li><font size="2" face="Arial">asyncRead returns IObservable&lt;int&gt;. As int is a value type and .NET variance on generics doesn’t allow casting from a value type to object.</font>  </li><li><font size="2" face="Arial">we’re not only interested in the completion of the asyncRead, but we' also like to know how many bytes were read so we can size our output array accordingly.</font> </li></ul> <p><font size="2" face="Arial">This is where the Start Operator comes in:</font></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">public static</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> ListObservable&lt;TSource&gt; Start&lt;TSource&gt;( <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">this</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;TSource&gt; source)</span></span></p></blockquote> <p><font size="2" face="Arial">T</font><font size="2" face="Arial">his operator takes any IObservable&lt;T&gt; and turns it into an object that implements IList&lt;T&gt; and IObservable&lt;object&gt;. As the source observable fires out values on OnNext, it will cache these values and make them available through the IList&lt;T&gt; implementation. Further it will fire OnCompleted on the IObservable&lt;Object&gt; interface once OnCompleted comes in on the source observable.</font></p> <p><font size="2" face="Arial">With the Start operator, we can now finish our AsyncReadHelper implementation:</font><span style="font-family: consolas; font-size: medium"><font size="4">&nbsp;</font></span></p> <blockquote style="background-color: #cccccc"> <p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">private</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">static</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IEnumerable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObservable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">object</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;&gt; AsyncReadHelper( <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">IObserver</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[]&gt; result, </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Stream</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> stream, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bufferSize) <br />{ <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> asyncRead = </span></span><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Observable</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">.FromAsyncPattern&lt;</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[], </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">, </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">int</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&gt;( <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">stream.BeginRead, stream.EndRead); <br />&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> buffer = </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">new</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">byte</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">[bufferSize]; </span></span></p> <p>&nbsp;</p> <p></p><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp; while</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> (</span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">true</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">) <br />&nbsp;&nbsp;&nbsp; { <br /></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> read = asyncRead(buffer, 0, bufferSize).Start(); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">yi</span></span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">eld</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">return</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> read;</span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><font color="#008000"><font color="#008000"><font color="#008000"> </font> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // As asyncRead returns an AsyncSubject, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and the Iterator operator takes care of exceptions, <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // we know at this point there will always be exactly one value in the list.</p></font></font></span></span></span></span>&nbsp; <br /></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> bytesRead = read[0]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium"><span style="font-family: consolas; color: #0000ff; font-size: medium">if</span></span></span><span style="font-family: consolas; font-size: medium"><span style="font-family: consolas; font-size: medium"> (bytesRead == 0) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br /><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium"><span style="font-family: consolas; color: #008000; font-size: medium">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // End of file</span></span></span></span></span><span style="font-family: consolas; font-size: medium">&nbsp;</span><span style="font-family: consolas"><span style="font-size: medium">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #0000ff"><span style="color: #0000ff"><span style="color: #0000ff">yield</span></span></span> <span style="color: #0000ff"><span style="color: #0000ff"><span style="color: #0000ff">break</span></span></span></span></span><span style="font-family: consolas; font-size: medium">; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span>  <p></p> <p><span style="font-family: consolas"><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var</span></span></span><span style="font-size: medium"><span style="font-size: medium"> outBuffer = </span></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">new</span></span></span><span style="font-size: medium"><span style="font-size: medium"> </span></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">byte</span></span></span></span><span style="font-size: medium"><span style="font-size: medium"><span style="font-family: consolas">[bytesRead]; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium"><span style="font-family: consolas; color: #2b91af; font-size: medium">Array</span></span></span><span style="font-size: medium"><span style="font-size: medium"><span style="font-family: consolas">.Copy(buffer, outBuffer, bytesRead);</span></span></span></p> <p><span style="font-size: medium"><span style="font-size: medium"><span style="font-family: consolas"><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Fire out to the outer Observable</span><span style="font-family: consolas"><span style="font-size: medium"> <br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.OnNext(outBuffer); <br /></span><span style="font-family: consolas">&nbsp;&nbsp;&nbsp; } <br /></span><span style="font-family: consolas">}</span></span></span></p></blockquote> <p><font size="2" face="Arial">And with that we have an extension method that will read the whole file asynchronously, exposing the data as an IObservable&lt;byte[]&gt;, opening a world of possibilities of windowing, grouping, and other operations we can do on the data.</font></p> <p><font size="2" face="Arial"><strong>Temperature of AsyncRead</strong></font></p> <p><font size="2" face="Arial">Our original version of AsyncRead was hot, our new version is neither hot, nor cold, more like luke-warm. Even though code created using the Iterator operator is generally cold, this is not the case here. As the System.IO.Stream object in .NET maintains state, so does our usage of it. The stream keeps track of the position in the file. If we were to subscribe two observers to this operator, unexpected things will happen. First it depends on if the specific Stream even supports two asynchronous reads at the same time. If it does, it will be a race, some of the data will be on the first observer and some will be on the second observer. Because of this it is best to only attach one observer to AsyncRead. If you really want to attach multiple observers, use the Publish operator on the resulting observable before subscribing.</font></p> <p><font size="2" face="Arial"><strong>What’s next?</strong></font></p> <p>So far we’ve seen how to use some advanced Rx operators to create an operator that will read in a file asynchronously and create an IObservable&lt;byte[]&gt; to signal the availability of the data. An operation that can be very useful on servers. Imagine an implementation of IHttpAsyncHandler that wants to dynamically read in a file on a slow network share.&nbsp; </p> <p>A set of byte[] might not be the most convenient way to look at the contents of a file though. Just like how in the synchronous world one would often prefer a StreamReader with functions like ReadLine over reading a byte[]. Next in this series we’ll talk about creating an asynchronous version of StreamReader functionality.</p>]]></content:encoded>
    </item>
    <item>
      <title>Node JS Bindings for RxJS</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/node-js-bindings-for-rxjs</link>
      <pubDate>Tue, 13 Apr 2010 18:56:00 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/04/13/node-js-bindings-for-rxjs/</guid>
      <description><![CDATA[Today during my presentation at JSConf, I showed that RxJS is not only about the browser. RxJS can...]]></description>
      <content:encoded><![CDATA[<p>Today during my presentation at <a mce_href="https://jsconf.us/2010" target="_blank" href="https://jsconf.us/2010">JSConf</a>, I showed that RxJS is not only about the browser. RxJS can be used anywhere JavaScript is available. To showcase that, the webserver I used for my dictionary suggest sample, was entirely written in JavaScript, using <a mce_href="https://www.nodejs.org" target="_blank" href="https://www.nodejs.org">node.js</a> as the engine.</p> <p>Attached to this post are the Rx bindings for node.js. With them you can use Rx to write asynchronous webservers. E.g. the Hello World sample from the <a mce_href="https://www.nodejs.org/" target="_blank" href="https://www.nodejs.org/">homepage of the node.js</a> project can be rewritten as follows:</p> <blockquote> <p><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">var</span></span><span style="font-size: medium"> </span><span style="font-size: medium">sys = </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">require</span></span><span style="font-size: medium">(</span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"sys"</span></span><span style="font-size: medium">);<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">var</span></span><span style="font-size: medium"> http = </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">require</span></span><span style="font-size: medium">(</span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">'./rx_http'</span></span><span style="font-size: medium">);<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">var</span></span><span style="font-size: medium"> serverData = http.createServer();serverData.Delay(2000).Subscribe(</span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">function</span></span><span style="font-size: medium">(details)<br>{<br>&nbsp;&nbsp;&nbsp; details.response.writeHead(200, { </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">'Content-Type'</span></span><span style="font-size: medium">: </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">'text/html'</span></span><span style="font-size: medium"> });<br>&nbsp;&nbsp;&nbsp; details.response.write(</span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"Hello World"</span></span><span style="font-size: medium">);<br>&nbsp;&nbsp;&nbsp; details.response.end();<br>});<br></span><span style="font-size: medium">serverData.server.listen(8000);<br>sys.puts(</span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">'Server running at <a mce_href="https://127.0.0.1:8000/'" href="https://127.0.0.1:8000/'">https://127.0.0.1:8000/'</a></span></span><span style="font-size: medium">);</span></p></blockquote> <p>of course, this is just a simple hello world. With operators like SelectMany and the bindings to all the file system operators, we can write great asynchronous webservers, but that is for a future post. Please let me know if you like these bindings. I’ll try to keep them up-to-date as both Rx.JS and node.js development continue.</p> <p>To use these bindings, copy rx.js from the official Rx download and add the files from <a mce_href="https://jeffrey.reactiveextensions.net/rx_nodejs.zip" target="_blank" href="https://jeffrey.reactiveextensions.net/rx_nodejs.zip">this zip</a> to the same directory.</p>]]></content:encoded>
    </item>
    <item>
      <title>On my way to JSConf</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/on-my-way-to-jsconf</link>
      <pubDate>Tue, 13 Apr 2010 18:35:30 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/04/13/on-my-way-to-jsconf/</guid>
      <description><![CDATA[This Saturday I’ll be presenting in Track B at JSConf, talking about Reactive Extensions for...]]></description>
      <content:encoded><![CDATA[<p>This Saturday I’ll be presenting in Track B at <a href="https://jsconf.us/2010/" target="_blank">JSConf</a>, talking about Reactive Extensions for JavaScript. I’ll show why RxJS matters, how to use it, show some features of the new release and reveal some slick unexpected uses of the library. So if you’re @ JSConf, don’t forget to attend my talk:</p> <p>Saturday April 17th 3:45PM - 4:15PM. <p>For those without tickets, <a href="https://jsconf.us/2010/videos.html" target="_blank">videos</a> will be posted afterwards ]]></content:encoded>
    </item>
    <item>
      <title>Time flies like an arrow in Script#</title>
      <link>https://docs.microsoft.com/archive/blogs/jeffva/time-flies-like-an-arrow-in-script</link>
      <pubDate>Fri, 26 Mar 2010 11:22:13 GMT</pubDate>
      <dc:creator><![CDATA[Jeffrey van Gogh - MS]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jeffva/2010/03/26/time-flies-like-an-arrow-in-script/</guid>
      <description><![CDATA[As kouPhax requested this on the Rx forum, I decided to post a port to Script# of the Time flies...]]></description>
      <content:encoded><![CDATA[<p>As kouPhax requested this on <a href="https://social.msdn.microsoft.com/Forums/en-US/rx/thread/bc7e472c-41be-407d-a3f9-5d949a972f76" target="_blank">the Rx forum</a>, I decided to post a port to Script# of the Time flies like an arrow sample that ships with <a href="https://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" target="_blank">Rx for JavaScript</a>. <p>Rx for JavaScript already ships with a binding for Script#, so that will make our lives a lot easier (you can find the binding in &lt;InstallPath&gt;\Redist\ScriptSharp\RxJs.dll) <p>For this sample I'll assume you have Script# 0.5.6.0 installed from <a href="https://projects.nikhilk.net/ScriptSharp" target="_blank">Nikhil's Script# site</a>.  <p>We start off with creating a Script# enabled website:  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_2.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb.png" width="741" height="483"></a>  <p>Next we open the Scriplet editor for the default Scriplet in the project:  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_4.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb_1.png" width="736" height="553"></a>  <p>We’ll make Script# aware of Rx by adding a reference to the RxJS.Dll:  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_6.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb_2.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb_2.png" width="729" height="503"></a>  <p>As well as the rx.js JavaScript file  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_8.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_8.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb_3.png" original-url="https://blogs.msdn.com/blogfiles/jeffva/WindowsLiveWriter/TimeflieslikeanarrowinScript_9FE3/image_thumb_3.png" width="735" height="507"></a>  <p>Next we’ll add the container div to the body of the Html page:  <p><font size="2">&lt;<span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">div</span></span><span style="font-size: medium"> </span><span style="color: #ff0000; font-size: medium"><span style="color: #ff0000; font-size: medium">id</span></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">="container"&gt;&lt;/</span></span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">div</span></span></font><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium"><font size="2">&gt;</font></span></span>  <p>Now it is time to do some coding:</p><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium"><font color="#0000ff" size="4"><font color="#0000ff" size="4"> <p><font size="2"><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">using</span></span></font><font size="2"><span style="font-size: medium"> </span></font></font></font></span></span><font size="2"><span style="font-size: medium">System;<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">using</span></span></font><font size="2"><span style="font-size: medium"> System.DHTML;<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">using</span></span></font><font size="2"><span style="font-size: medium"> ScriptFX;<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">using</span></span></font><font size="2"><span style="font-size: medium"> ScriptFX.UI;<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">using</span></span></font><font size="2"><span style="font-size: medium"> Rx;<br></span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">public</span></span><span style="font-size: medium"> </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">class</span></span><span style="font-size: medium"> </span></font><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium"><font size="2">MyScriptlet<br></font></span></span><font size="2"><span style="font-size: medium">{<br>&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">public</span></span><span style="font-size: medium"> </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">static</span></span><span style="font-size: medium"> </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">void</span></span><span style="font-size: medium"> Main(</span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">ScriptletArguments</span></span></font><font size="2"><span style="font-size: medium"> arguments) <br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">DOMDocument</span></span><span style="font-size: medium"> document = </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">Window</span></span></font><font size="2"><span style="font-size: medium">.Document;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">Observable</span></span><span style="font-size: medium"> mouseMove = </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">Observable</span></span><span style="font-size: medium">.FromHtmlEvent(document, </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"mousemove"</span></span></font><font size="2"><span style="font-size: medium">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">string</span></span><span style="font-size: medium"> text = </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"time flies like an arrow"</span></span></font><font size="2"><span style="font-size: medium">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">DOMElement</span></span><span style="font-size: medium"> container = document.GetElementById(</span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"container"</span></span></font><font size="2"><span style="font-size: medium">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">for</span></span><span style="font-size: medium"> (</span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">int</span></span></font><font size="2"><span style="font-size: medium"> i = 0; i &lt; text.Length; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">ActionInt32</span></span><span style="font-size: medium"> closure = </span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">delegate</span></span><span style="font-size: medium"> (</span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">int</span></span></font><font size="2"><span style="font-size: medium"> j)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">DOMElement</span></span><span style="font-size: medium"> s = document.CreateElement(</span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"span"</span></span></font><font size="2"><span style="font-size: medium">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.InnerHTML = text.CharAt(j).ToString();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Style.Position = </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"absolute"</span></span></font><font size="2"><span style="font-size: medium">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; container.AppendChild(s);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mouseMove.Delay(j * 100).Subscribe(</span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">delegate</span></span><span style="font-size: medium">(</span><span style="color: #0000ff; font-size: medium"><span style="color: #0000ff; font-size: medium">object</span></span></font><font size="2"><span style="font-size: medium"> o)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">Event</span></span><span style="font-size: medium"> mouseEvent = (</span><span style="color: #2b91af; font-size: medium"><span style="color: #2b91af; font-size: medium">Event</span></span></font><font size="2"><span style="font-size: medium">)o;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s.Style.Top = mouseEvent.OffsetY + </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"px"</span></span></font><font size="2"><span style="font-size: medium">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: medium">s.Style.Left = mouseEvent.OffsetX + j * 10 + 15 + </span><span style="color: #a31515; font-size: medium"><span style="color: #a31515; font-size: medium">"px"</span></span></font><span style="font-size: medium"><font size="2">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closure(i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span><span style="font-size: medium"><font size="2">}<br>&nbsp;&nbsp; }<br>}</font></span></p> <p>As you can see the code looks very similar to <a href="https://blogs.msdn.com/jeffva/archive/2010/03/17/reactive-extensions-for-javascript-the-time-flies-like-an-arrow-sample.aspx" target="_blank">the JavaScript version</a>, just adding a few types. One of the interesting things is that just like in the JavaScript version, you’ll need to put a manual closure inside the for loop. The reason for this is that Script# gives you C# syntax, but maintains JavaScript semantics.</p> <p>There you have it, your first Rx Script# app. Any feedback on Rx for Script# is of course welcome on <a href="https://social.msdn.microsoft.com/Forums/en-US/rx/threads" target="_blank">the Rx forum</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>