<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><!--Generated by Squarespace V5 Site Server v5.13.147 (http://www.squarespace.com) on Mon, 29 Apr 2013 06:35:28 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><title>Blog</title><subtitle>Blog</subtitle><id>http://george.tsiokos.com/posts/</id><link rel="alternate" type="application/xhtml+xml" href="http://george.tsiokos.com/posts/" /><updated>2012-11-25T23:28:27Z</updated><generator uri="http://five.squarespace.com/" version="Squarespace V5 Site Server v5.13.147 (http://www.squarespace.com)">Squarespace</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/george_tsiokos" /><feedburner:info uri="george_tsiokos" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><entry><title>I'm lucky</title><category term="General" /><id>http://george.tsiokos.com/posts/2012/11/25/im-lucky.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/RchRa3P-Xe0/im-lucky.html" /><author><name>George Tsiokos</name></author><published>2012-11-25T23:23:34Z</published><updated>2012-11-25T23:23:34Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Today I received an email stating I'm entitled to $1.5 million dollars. The only decision I need to make is if I should receive an ATM card to use that money, or, if I should opt for a check. There are benefits to either decision. Recommendations?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;US-FBI-ShadedSeal.svg&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Federal Bureau of Investigation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;FBI Seattle Division&lt;/span&gt;&lt;br /&gt;&lt;span&gt;1110 Third Avenue&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Seattle. 98101-2904&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Attn:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;This is Robert S. Mueller III of Federal Bureau of Investigation (FBI) The FBI in alliance with the Economic Community of West Asia States (ECOWAS), with their Head Office there in West Africa has been working towards the total eradication of fraudsters and scam in the Western part of West Africa With the help of the United States Government and the (U.N) United Nations. We have been able to track down so many of this scammers in various parts of African Region, which includes ( REPUBLIC OF BENIN, TOGO, GHANA CAMEROON, SENEGAL AND NIGERIA) and they are all in our custody over there, meanwhile during the process of arrest, We were able to recover some funds from the prosecuted scammer.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Regarding this great achievement, the (U.N) United Nations Anti-crime commission and the United State Government have ordered that the money recovered from these Scammers be shared among 100 Lucky people around the globe. This email is been directed to you because your email address was found in one of the file and computer hard disk recovered from the prosecuted scammers there in our custody. You are therefore being compensated with the sum of $1.5 Million Dollars. We have also arrested all those who claimed to be Barristers, Bank Officials, Lottery Agents, Person or group of Person's who claim to have funds in their custody that belonged to you or want you to be the Next of kin of such funds which do not exist.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;Now how would you like to receive your payment? Because we have two method of payment which is by Check or by ATM card?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;ATM Card: We will be issuing you a custom pin based ATM card which you will use to withdraw up to $3,000 per day from any ATM machine that has the Master Card Logo on it and the card have to be renewed in 4 years time which is 2016. Also with the ATM card you will be able to transfer your funds to your local bank account. The ATM card comes with a handbook or manual to enlighten you about how to use it, even if you do not have a bank account.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Check: To be deposited in your bank for it to be cleared within three working days. Your payment would be sent to you via any of your preferred option and would be mailed to you via UPS. Because we have signed a contract with UPS which should expire in next three weeks, you will only need to pay $205 instead of $420 saving you $215 So if you pay before the three weeks in October 25, 2012 you save $215 Take note that anyone asking you for some kind of money above the usual fee of $205usd is definitely a fraudsters and you will have to stop communication with every other person if you have been in contact with any.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=RchRa3P-Xe0:0z2mK4fw4MM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=RchRa3P-Xe0:0z2mK4fw4MM:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=RchRa3P-Xe0:0z2mK4fw4MM:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=RchRa3P-Xe0:0z2mK4fw4MM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=RchRa3P-Xe0:0z2mK4fw4MM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/RchRa3P-Xe0" height="1" width="1"/&gt;</content><link rel="enclosure" type="application/pdf" href="http://george.tsiokos.com/storage/I'm lucky.pdf" length="63048" /><feedburner:origLink>http://george.tsiokos.com/posts/2012/11/25/im-lucky.html</feedburner:origLink></entry><entry><title>Different async options in .NET</title><category term=".NET" /><category term="asynchronous" /><category term="c#" /><category term="rx" /><id>http://george.tsiokos.com/posts/2011/8/28/different-async-options-in-net.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/dQy12dCq8DE/different-async-options-in-net.html" /><author><name>George Tsiokos</name></author><published>2011-08-28T21:40:41Z</published><updated>2011-08-28T21:40:41Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;To demonstrate the different async options in .NET, I wrote the following samples that call the async read methods of the .NET FileStream. The following&amp;nbsp;APM, TPL, and Rx code samples complete in roughly the same amount of time.&amp;nbsp;I am biased to Rx, so, it's the most elegent code sample of them all.&lt;/p&gt;
&lt;h2&gt;APM sample&lt;/h2&gt;
&lt;pre style="font-family: Consolas; background: #171e1f; color: #d6ded4; font-size: 13px;"&gt;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;count&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;;
&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[]&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;buffer&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[&lt;span style="color: #c7c7a5;"&gt;__bufferSize&lt;/span&gt;];
&lt;span style="color: #afc81c;"&gt;ManualResetEventSlim&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;flag&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;ManualResetEventSlim&lt;/span&gt;&amp;nbsp;();
&lt;span style="color: #80ff00;"&gt;Action&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;null&lt;/span&gt;;
&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;()&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;fileStream&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;BeginRead&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;buffer&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;__bufferSize&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;ar&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;bytesRead&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;fileStream&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;EndRead&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;ar&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;if&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;==&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;bytesRead&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;flag&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Set&lt;/span&gt;&amp;nbsp;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;else&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;if&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;count&lt;/span&gt;&lt;span style="color: gray;"&gt;++&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;__count&lt;/span&gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;Console&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;WriteLine&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;stopwatch&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Elapsed&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;count&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
},&amp;nbsp;&lt;span style="color: #498091;"&gt;null&lt;/span&gt;);
 
&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;();
&lt;span style="color: #c7c7a5;"&gt;flag&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Wait&lt;/span&gt;&amp;nbsp;();&lt;/pre&gt;
&lt;p&gt;A counter, buffer, and waithandle are created. An action delegate calls the beginRead delegate, and registers an anonymous delegate as the callback. In this callback, the EndRead method is called which returns the bytesRead. If it's zero, the waithandle is signaled and the method exits, otherwise, a count is increased (and checked against a constant to write progress), and calls itself to loop.&lt;/p&gt;
&lt;h2&gt;TPL sample&lt;/h2&gt;
&lt;pre style="font-family: Consolas; background: #171e1f; color: #d6ded4; font-size: 13px;"&gt;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;count&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;;
&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[]&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;buffer&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[&lt;span style="color: #c7c7a5;"&gt;__bufferSize&lt;/span&gt;];
&lt;span style="color: #afc81c;"&gt;ManualResetEventSlim&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;flag&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;ManualResetEventSlim&lt;/span&gt;&amp;nbsp;();
 
&lt;span style="color: #80ff00;"&gt;Func&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #afc81c;"&gt;Task&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;readAsync&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;()&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;Task&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Factory&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;FromAsync&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[],&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;fileStream&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;BeginRead&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;fileStream&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;EndRead&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;buffer&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;__bufferSize&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;null&lt;/span&gt;);
 
&lt;span style="color: #80ff00;"&gt;Action&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;null&lt;/span&gt;;
&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;()&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;readAsync&lt;/span&gt;&amp;nbsp;()&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;ContinueWith&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;task&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;if&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;==&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;task&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Result&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;flag&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Set&lt;/span&gt;&amp;nbsp;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;else&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #498091;"&gt;if&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;count&lt;/span&gt;&lt;span style="color: gray;"&gt;++&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;__count&lt;/span&gt;)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;Console&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;WriteLine&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;stopwatch&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Elapsed&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;count&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});
};
 
&lt;span style="color: #c7c7a5;"&gt;read&lt;/span&gt;&amp;nbsp;();
&lt;span style="color: #c7c7a5;"&gt;flag&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Wait&lt;/span&gt;&amp;nbsp;();&lt;/pre&gt;
&lt;p&gt;An action delegate invokes the task and hooks in a continuation delegate to handle the completion. In the continuation if the result is 0 the waithandle is set and the method exists. Otherwise the count in increased&amp;nbsp; (and checked against a constant to write progress), and calls itself to loop.&lt;/p&gt;
&lt;h2&gt;Rx sample&lt;/h2&gt;
&lt;pre style="font-family: Consolas; background: #171e1f; color: #d6ded4; font-size: 13px;"&gt;&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[]&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;buffer&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[&lt;span style="color: #c7c7a5;"&gt;__bufferSize&lt;/span&gt;];
&lt;span style="color: #498091;"&gt;var&lt;/span&gt;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;readAsync&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;Observable&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;FromAsyncPattern&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #498091;"&gt;byte&lt;/span&gt;[],&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #498091;"&gt;int&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;fileStream&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;BeginRead&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;fileStream&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;EndRead&lt;/span&gt;);
 
&lt;span style="color: #afc81c;"&gt;Observable&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Repeat&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;).&lt;span style="color: #c7c7a5;"&gt;SelectMany&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;_&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;readAsync&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;buffer&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;__bufferSize&lt;/span&gt;))&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;TakeWhile&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;bytesRead&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;bytesRead&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: #6dabd8;"&gt;0&lt;/span&gt;)&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Buffer&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;__count&lt;/span&gt;)&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;ForEach&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #c7c7a5;"&gt;results&lt;/span&gt;&amp;nbsp;&lt;span style="color: gray;"&gt;=&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #afc81c;"&gt;Console&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;WriteLine&lt;/span&gt;&amp;nbsp;(&lt;span style="background: #374626; color: #99b478; font-weight: bold;"&gt;"{0}&amp;nbsp;min:{1}&amp;nbsp;max:{2}&amp;nbsp;count:{3}"&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;stopwatch&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Elapsed&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;results&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Min&lt;/span&gt;&amp;nbsp;(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;results&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Max&lt;/span&gt;&amp;nbsp;(),
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #c7c7a5;"&gt;results&lt;/span&gt;&lt;span style="color: gray;"&gt;.&lt;/span&gt;&lt;span style="color: #c7c7a5;"&gt;Count&lt;/span&gt;));&lt;/pre&gt;
&lt;p&gt;&lt;br /&gt;A infinite sequence of 0 is created, the value 0 is ignored by the SelectMany operator by invoking the observable factory function, constrain the sequence to only observe when bytesRead &amp;gt; 0, buffer the results into a sequence of IList&amp;lt;int&amp;gt; and we block with the ForEach operator to display the progress to the console.&lt;/p&gt;
&lt;p&gt;Thanks to &lt;a href="http://weblogs.asp.net/davidfowler/"&gt;David Fowler&lt;/a&gt; for recomending the idea to compare the differences between the different aync options in .NET!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=dQy12dCq8DE:IQU581xkClY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=dQy12dCq8DE:IQU581xkClY:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=dQy12dCq8DE:IQU581xkClY:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=dQy12dCq8DE:IQU581xkClY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=dQy12dCq8DE:IQU581xkClY:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/dQy12dCq8DE" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2011/8/28/different-async-options-in-net.html</feedburner:origLink></entry><entry><title>IEnumerable &amp; IObservable Split ()</title><category term=".NET" /><category term="LINQ" /><category term="c#" /><category term="rx" /><id>http://george.tsiokos.com/posts/2011/1/10/ienumerable-iobservable-split.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/tD-I58TP-cw/ienumerable-iobservable-split.html" /><author><name>George Tsiokos</name></author><published>2011-01-10T14:00:20Z</published><updated>2011-01-10T14:00:20Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Another IObservable&amp;lt;&amp;gt; extension method I needed was Split &amp;ndash; just like string.Split (), but generically for any array and an IObservable&amp;lt;T[]&amp;gt;. I started first with a generic IEnumberable&amp;lt;T&amp;gt; Split&amp;lt;T&amp;gt; ():&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; Returns one or more arrays that contains the subarrays in this&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; instance that are delimited by elements of a specified array.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"T"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;type of the array&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"value"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;value to split&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"separator"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;one or more separators&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;not efficient with separator lengths &amp;gt; 1&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;T[]&amp;gt; Split&amp;lt;T&amp;gt; (&lt;span style="color: blue;"&gt;this&lt;/span&gt; T[] value, &lt;span style="color: blue;"&gt;params&lt;/span&gt; T[] separator) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; separatorLength = separator.Length;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; startingIndex = 0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; index = -1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;int&lt;/span&gt; length;&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;do&lt;/span&gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;/* loop through each item in the separator&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * array verifing it exists in the source array */&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;for&lt;/span&gt; (&lt;span style="color: blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; separatorLength; i++) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; index = &lt;span style="color: #2b91af;"&gt;Array&lt;/span&gt;.IndexOf (value, separator[i], startingIndex);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (-1 == index)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (-1 &amp;lt; index) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// delimiter matched successfully&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; length = index - startingIndex;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; T[] output = &lt;span style="color: blue;"&gt;new&lt;/span&gt; T[length];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Array&lt;/span&gt;.Copy (value, startingIndex, output, 0, length);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt; output;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; startingIndex = index + 1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="color: blue;"&gt;while&lt;/span&gt; (-1 &amp;lt; index);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (0 == startingIndex)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// no match, send entire value&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt; value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;else&lt;/span&gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;// no more matches, send items left&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; length = value.Length - startingIndex;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; T[] output = &lt;span style="color: blue;"&gt;new&lt;/span&gt; T[length];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;Array&lt;/span&gt;.Copy (value, startingIndex, output, 0, length);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Now that I can split an array, I need to an IObservable&amp;lt;T[]&amp;gt; Split() as well:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; Splits the arrays from the source observable by the separator&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"TSource"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;type of the source array&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"source"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;source array&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"separator"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;the separator(s)&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;An observable containing the same number of items (if the &lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; separator(s) are not found) or additional items by spliting the incoming&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; arrays&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource[]&amp;gt; Split&amp;lt;TSource&amp;gt; (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource[]&amp;gt; source, &lt;span style="color: blue;"&gt;params&lt;/span&gt; TSource[][] separator) {&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (source == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentNullException&lt;/span&gt; (&lt;span style="color: #a31515;"&gt;"source"&lt;/span&gt;, &lt;span style="color: #a31515;"&gt;"source is null."&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (separator.Length &amp;lt; 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentOutOfRangeException&lt;/span&gt; (&lt;span style="color: #a31515;"&gt;"separator"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource[]&amp;gt; value = source;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green;"&gt;/* foreach of the delimiter arrays passed in&lt;/span&gt;&lt;br /&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * chain the call to Split () */&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; separator.Run (item =&amp;gt; value = value.Split (item));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt; value;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; Splits the arrays from the source observable by the delimiter&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;typeparam name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"TSource"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;type of the source array&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"source"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;source array&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;param name=&lt;/span&gt;&lt;span style="color: gray;"&gt;"separator"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;the delimiter&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: green;"&gt;An observable containing the same number of items (if the &lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; delimiter is not found) or additional items by spliting the incoming&lt;/span&gt;&lt;br /&gt;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt; arrays&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource[]&amp;gt; Split&amp;lt;TSource&amp;gt; (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;TSource[]&amp;gt; source, &lt;span style="color: blue;"&gt;params&lt;/span&gt; TSource[] separator) {&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (source == &lt;span style="color: blue;"&gt;null&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentNullException&lt;/span&gt; (&lt;span style="color: #a31515;"&gt;"source"&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;if&lt;/span&gt; (separator.Length &amp;lt; 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentOutOfRangeException&lt;/span&gt; (&lt;span style="color: #a31515;"&gt;"delimiter"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Observable&lt;/span&gt;.CreateWithDisposable&amp;lt;TSource[]&amp;gt; (observer =&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; source.Subscribe&amp;lt;TSource[]&amp;gt; (value =&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value.Split (separator).Run (observer.OnNext),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; observer.OnError, observer.OnCompleted)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; );&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Of course these extension methods can be further optimized and handle more use cases - especially by using IList&amp;lt;T&amp;gt; instead of array.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=tD-I58TP-cw:Awwcs8paEwc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=tD-I58TP-cw:Awwcs8paEwc:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=tD-I58TP-cw:Awwcs8paEwc:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=tD-I58TP-cw:Awwcs8paEwc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=tD-I58TP-cw:Awwcs8paEwc:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/tD-I58TP-cw" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2011/1/10/ienumerable-iobservable-split.html</feedburner:origLink></entry><entry><title>ReverseAsyncRead ()</title><category term=".NET" /><category term="c#" /><category term="rx" /><id>http://george.tsiokos.com/posts/2011/1/3/reverseasyncread.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/MywI4SlbwLU/reverseasyncread.html" /><author><name>George Tsiokos</name></author><published>2011-01-03T13:03:29Z</published><updated>2011-01-03T13:03:29Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;Rx includes the AsyncRead () method that reads a stream from the beginning returning an IObservable&amp;lt;byte[]&amp;gt;. This method does the same, but in reverse. The public method overloads accept a stream and optionally a bufferSize and startingPosition.&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;stream)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(stream,&amp;nbsp;2&amp;nbsp;&amp;lt;&amp;lt;&amp;nbsp;15);&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;stream,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;nbsp;bufferSize)&amp;nbsp;{&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ValidateParameters&amp;nbsp;(stream,&amp;nbsp;bufferSize);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Observable&lt;/span&gt;.Iterate&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;&amp;nbsp;(observer&amp;nbsp;=&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(stream,&amp;nbsp;bufferSize,&amp;nbsp;observer,&amp;nbsp;stream.Length));&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;this&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;stream,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;nbsp;bufferSize,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;long&lt;/span&gt;&amp;nbsp;startingPosition)&amp;nbsp;{&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ValidateParameters&amp;nbsp;(stream,&amp;nbsp;bufferSize);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&amp;nbsp;(0&amp;nbsp;&amp;gt;&amp;nbsp;startingPosition)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentOutOfRangeException&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #a31515;"&gt;"startingPosition"&lt;/span&gt;);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Observable&lt;/span&gt;.Iterate&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;&amp;nbsp;(observer&amp;nbsp;=&amp;gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(stream,&amp;nbsp;bufferSize,&amp;nbsp;observer,&amp;nbsp;startingPosition));&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Using IEnumerable&amp;lt;IObservable&amp;lt;object&amp;gt;&amp;gt;, yield, Observable.FromAsyncPattern (), and Observable.Iterate (), we&amp;rsquo;re able to read a stream in blocks (of bufferSize) from the end to the front.&amp;nbsp;The public method calls Iterate () which passes an observer instance to the following private method:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;void&lt;/span&gt;&amp;nbsp;ValidateParameters&amp;nbsp;(&lt;span style="color: #2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;stream,&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;nbsp;bufferSize)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&amp;nbsp;(&lt;span style="color: blue;"&gt;null&lt;/span&gt;&amp;nbsp;==&amp;nbsp;stream)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentNullException&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #a31515;"&gt;"stream"&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&amp;nbsp;(!stream.CanSeek)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentOutOfRangeException&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #a31515;"&gt;"stream"&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #a31515;"&gt;"stream.CanSeek&amp;nbsp;is&amp;nbsp;false"&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&amp;nbsp;(1&amp;nbsp;&amp;gt;&amp;nbsp;bufferSize)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ArgumentOutOfRangeException&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #a31515;"&gt;"bufferSize"&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;&lt;span style="color: blue;"&gt;static&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;object&lt;/span&gt;&amp;gt;&amp;gt;&amp;nbsp;ReverseAsyncRead&amp;nbsp;(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Stream&lt;/span&gt;&amp;nbsp;stream,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;nbsp;bufferSize,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObserver&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;gt;&amp;nbsp;observer,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;long&lt;/span&gt;&amp;nbsp;startingPosition)&amp;nbsp;{&lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Func&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[],&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #2b91af;"&gt;IObservable&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;gt;&amp;nbsp;asyncRead&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Observable&lt;/span&gt;.FromAsyncPattern&amp;lt;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[],&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;,&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;nbsp;(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stream.BeginRead,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stream.EndRead);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[]&amp;nbsp;buffer&amp;nbsp;=&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;byte&lt;/span&gt;[bufferSize];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;long&lt;/span&gt;&amp;nbsp;position&amp;nbsp;=&amp;nbsp;startingPosition;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;nbsp;read&amp;nbsp;=&amp;nbsp;bufferSize;&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;do&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&amp;nbsp;decrement&amp;nbsp;position&amp;nbsp;by&amp;nbsp;the&amp;nbsp;amount&amp;nbsp;read&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position&amp;nbsp;-=&amp;nbsp;read;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&amp;nbsp;(position&amp;nbsp;&amp;lt;&amp;nbsp;0)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;bufferSize&amp;nbsp;=&amp;nbsp;(&lt;span style="color: blue;"&gt;int&lt;/span&gt;)position&amp;nbsp;*&amp;nbsp;-1;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;position&amp;nbsp;=&amp;nbsp;0;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&amp;nbsp;set&amp;nbsp;stream's&amp;nbsp;position&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stream.Position&amp;nbsp;=&amp;nbsp;position;&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&amp;nbsp;call&amp;nbsp;stream's&amp;nbsp;Begin/End&amp;nbsp;Read&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;ListObservable&lt;/span&gt;&amp;lt;&lt;span style="color: blue;"&gt;int&lt;/span&gt;&amp;gt;&amp;nbsp;asyncReadResult;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;asyncReadResult&amp;nbsp;=&amp;nbsp;asyncRead&amp;nbsp;(buffer,&amp;nbsp;0,&amp;nbsp;bufferSize).Start&amp;nbsp;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt;&amp;nbsp;exception)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.OnError&amp;nbsp;(exception);&amp;nbsp;&lt;span style="color: blue;"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;asyncReadResult;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;read&amp;nbsp;=&amp;nbsp;asyncReadResult.Value;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&amp;nbsp;send&amp;nbsp;value&amp;nbsp;read&amp;nbsp;to&amp;nbsp;observer&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;try&lt;/span&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;if&lt;/span&gt;&amp;nbsp;(bufferSize&amp;nbsp;==&amp;nbsp;read)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.OnNext&amp;nbsp;(buffer);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;else&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.OnNext&amp;nbsp;(buffer.Take&amp;nbsp;(read).ToArray&amp;nbsp;());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;catch&lt;/span&gt;&amp;nbsp;(&lt;span style="color: #2b91af;"&gt;Exception&lt;/span&gt;&amp;nbsp;exception)&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.OnError&amp;nbsp;(exception);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;yield&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;break&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: green;"&gt;//&amp;nbsp;continue&amp;nbsp;until&amp;nbsp;we&amp;nbsp;can't&amp;nbsp;read&amp;nbsp;anymore&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;span style="color: blue;"&gt;while&lt;/span&gt;&amp;nbsp;(read&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;position&amp;nbsp;&amp;gt;&amp;nbsp;0);&lt;br /&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.OnCompleted&amp;nbsp;();&lt;br /&gt;}&lt;/pre&gt;
&lt;p&gt;Using yield and Stream&amp;rsquo;s async method calls, we&amp;rsquo;re able to observe all byte[] blocks in the stream reading backwards.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MywI4SlbwLU:tYK0RfelYt8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MywI4SlbwLU:tYK0RfelYt8:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=MywI4SlbwLU:tYK0RfelYt8:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MywI4SlbwLU:tYK0RfelYt8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MywI4SlbwLU:tYK0RfelYt8:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/MywI4SlbwLU" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2011/1/3/reverseasyncread.html</feedburner:origLink></entry><entry><title>Optimizing tail with Rx</title><category term=".NET" /><category term="LINQ" /><category term="c#" /><category term="rx" /><category term="tail" /><id>http://george.tsiokos.com/posts/2010/12/29/optimizing-tail-with-rx.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/OVk8NMDKi-c/optimizing-tail-with-rx.html" /><author><name>George Tsiokos</name></author><published>2010-12-29T14:00:01Z</published><updated>2010-12-29T14:00:01Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;&lt;a href="http://yzorgsoft.blogspot.com/"&gt;Chris&lt;/a&gt;&amp;nbsp;was concerned that the initial Rx implementation was inefficiently reading an entire 5 GB text file throwing everything away except for the last 10 lines. To optimize I/O, I've modified the code to read the file in reverse. Here's a new version that tails a 5 GB text file in less than 150 ms:&lt;/p&gt;
&lt;pre style="line-height: normal;"&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;const&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; bufferSize = 2 &amp;lt;&amp;lt; 15;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;using&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; stream = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileStream&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt; (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; args[0], &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;FileMode&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Open, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileAccess&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Read, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileShare&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Read, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bufferSize, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileOptions&lt;/span&gt;&lt;span style="color: #000000;"&gt;.Asynchronous | &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileOptions&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.RandomAccess)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #008000;"&gt;// seek to (EOF - bufferSize) and read stream backwards, returning IObservable&amp;lt;byte[]&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream.ReverseAsyncRead (bufferSize)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span&gt;&lt;span style="color: #008000;"&gt;// reverse bytes inside byte[]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Select(bytes =&amp;gt; bytes.Reverse().ToArray())&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #008000;"&gt;// split byte[] on \r and \n&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Split (&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;[] { 13 }, &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;[] { 10 })&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;"&gt;// take 10 of the byte[] results&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Take (10)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;"&gt;// reverse order of byte[]s, and the bytes inside the byte[]s&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .ToEnumerable ().Reverse ().Select (bytes =&amp;gt; bytes.Reverse ().ToArray ()).ToObservable ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;"&gt;// using ASCII encoding, convert bytes to string&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Decode (&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;Encoding&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;.ASCII)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #008000;"&gt;// output the IObservable&amp;lt;string&amp;gt; to the standard output&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .Run (&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.WriteLine);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Starting from the end of the file, reading chunks backwards, reversing the byte[] chunks, delimiting by \r and \n (creating smaller byte[] results), take the first 10, reversing them back, converting to string (via ASCII encoding), and then sending to standard output. In this version we are reading from disk only the information required to tail the file - no unnecessary disk IOs. Unfortunately some of these extension methods didn't exist, so I had to create three to build this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://george.tsiokos.com/posts/2011/1/3/reverseasyncread.html"&gt;ReverseAsyncRead&lt;/a&gt; (this Stream): just like AsyncRead (), but in reverse &lt;/li&gt;
&lt;li&gt;Split&amp;lt;T&amp;gt; (this T[]): just like string.Split (), but generic, for any array, and for observable input arrays &lt;/li&gt;
&lt;li&gt;Decode (this byte[]): using Encoding and a Decoder, converts a IObservable&amp;lt;byte[]&amp;gt; to IObservable&amp;lt;string&amp;gt; &lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=OVk8NMDKi-c:z4cDu1rVE78:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=OVk8NMDKi-c:z4cDu1rVE78:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=OVk8NMDKi-c:z4cDu1rVE78:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=OVk8NMDKi-c:z4cDu1rVE78:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=OVk8NMDKi-c:z4cDu1rVE78:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/OVk8NMDKi-c" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2010/12/29/optimizing-tail-with-rx.html</feedburner:origLink></entry><entry><title>Implementing tail with .NET &amp; Rx</title><category term=".NET" /><category term="c#" /><category term="rx" /><category term="tail" /><id>http://george.tsiokos.com/posts/2010/12/27/implementing-tail-with-net-rx.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/bSoGCeaoOcE/implementing-tail-with-net-rx.html" /><author><name>George Tsiokos</name></author><published>2010-12-27T13:01:35Z</published><updated>2010-12-27T13:01:35Z</updated><content type="html" xml:lang="en-US">&lt;p&gt;By default the tail command-line utility displays the last 10 lines of a file to standard output. To learn Rx, I endeavor to create a full .NET 4.0 version of tail. Here's the initial version:&lt;/p&gt;
&lt;pre style="line-height: normal;"&gt;&lt;span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;&lt;span&gt;using&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; stream = &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileStream&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt; (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; args[0],&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileMode&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;.Open,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileAccess&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;.Read,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;FileShare&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;.Read,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 &amp;lt;&amp;lt; 15,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span&gt;&lt;span style="color: #0000ff;"&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span style="color: #000000;"&gt;)) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream.AsyncReadLines ().TakeLast (10).Run (&lt;/span&gt;&lt;span&gt;&lt;span style="color: #2b91af;"&gt;Console&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.WriteLine);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The majority of this code is the .NET call to open the file using async I/O. The 1&lt;sup&gt;st&lt;/sup&gt; Rx method call is AsyncReadLines () which transforms the .NET stream into an IObservable&amp;lt;string&amp;gt;. TakeLast(10) ignores all strings observed except for the last 10 lines. Run() blocks the current thread until the IObservable&amp;lt;T&amp;gt; fires OnCompleted(), and I also pass in Console.WriteLine as the argument to use for the Action&amp;lt;string&amp;gt; delegate to write the last ten lines to the console. The output of this code is identical to running tail without any parameters.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=bSoGCeaoOcE:PU0RY6Ttvio:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=bSoGCeaoOcE:PU0RY6Ttvio:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=bSoGCeaoOcE:PU0RY6Ttvio:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=bSoGCeaoOcE:PU0RY6Ttvio:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=bSoGCeaoOcE:PU0RY6Ttvio:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/bSoGCeaoOcE" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2010/12/27/implementing-tail-with-net-rx.html</feedburner:origLink></entry><entry><title>Sequence membership</title><category term="LINQ" /><category term="c#" /><id>http://george.tsiokos.com/posts/2008/12/10/sequence-membership.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/8lFrd_TdbgM/sequence-membership.html" /><author><name>George Tsiokos</name></author><published>2008-12-10T05:06:46Z</published><updated>2008-12-10T05:06:46Z</updated><content type="html" xml:lang="en-US">Given two &lt;strong&gt;sorted sequences&lt;/strong&gt;, this method returns the intersection, a-b, and b-a, using a single iteration over both sequences. The return type is an  IEnumerable&amp;lt;KeyValuePair&amp;lt;T, int&amp;gt;&amp;gt;, where:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;only in A = -1&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;in both = 0&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;only in B = 1&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt; &lt;br/&gt;&lt;pre&gt;/// &amp;lt;summary&amp;gt;&lt;br/&gt;/// Return an int for every element in sortedSetA and sortedSetB specifying objects&lt;br/&gt;/// that belong to A but not to B (-1), objects which are both in A and in B (0), and objects&lt;br/&gt;/// that belong to B but not A (1).&lt;br/&gt;/// &amp;lt;/summary&amp;gt;&lt;br/&gt;/// &amp;lt;remarks&amp;gt;This method is an O(n+m) operation when the two sets have different members, where n &lt;br/&gt;/// is the count of &amp;lt;paramref name=&amp;quot;sortedSetA&amp;quot;/&amp;gt; and m is the count of &amp;lt;paramref name=&amp;quot;sortedSetB&amp;quot;/&amp;gt;.&lt;br/&gt;/// Otherwise the operation approaches O(n+m-n) where m is the count of the larger set and n is the&lt;br/&gt;/// smaller set.&lt;br/&gt;/// &amp;lt;/remarks&amp;gt;&lt;br/&gt;/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;Type of element in each set&amp;lt;/typeparam&amp;gt;&lt;br/&gt;/// &amp;lt;param name=&amp;quot;setA&amp;quot;&amp;gt;A set where each element is of type &amp;lt;typeparamref name=&amp;quot;T&amp;quot;/&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;/// &amp;lt;param name=&amp;quot;setB&amp;quot;&amp;gt;A set where each element is of type &amp;lt;typeparamref name=&amp;quot;T&amp;quot;/&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;/// &amp;lt;returns&amp;gt;Returns A \ B (-1), the intersection of A and B (0), and B \ A (1)&amp;lt;/returns&amp;gt;&lt;br/&gt;public static IEnumerable&amp;lt;KeyValuePair&amp;lt;T, int&amp;gt;&amp;gt; Membership&amp;lt;T&amp;gt; (IEnumerable&amp;lt;T&amp;gt; sortedSetA, IEnumerable&amp;lt;T&amp;gt; sortedSetB) {&lt;br/&gt;    return Membership&amp;lt;T&amp;gt; (sortedSetA, sortedSetB, Comparer&amp;lt;T&amp;gt;.Default);&lt;br/&gt;}&lt;br/&gt;/// &amp;lt;summary&amp;gt;&lt;br/&gt;/// Return a KeyValuePair&amp;lt;int, T&amp;gt; for every element in sortedSetA and sortedSetB where the int&lt;br/&gt;/// specifies membership and T is the element. The int specifies objects that belong to A but&lt;br/&gt;/// not to B (-1), objects which are both in A and in B (0), and objects that belong to B but&lt;br/&gt;/// not A (1).&lt;br/&gt;/// &amp;lt;/summary&amp;gt;&lt;br/&gt;/// &amp;lt;remarks&amp;gt;This method is an O(n+m) operation when the two sets have different members, where n &lt;br/&gt;/// is the count of &amp;lt;paramref name=&amp;quot;sortedSetA&amp;quot;/&amp;gt; and m is the count of &amp;lt;paramref name=&amp;quot;sortedSetB&amp;quot;/&amp;gt;.&lt;br/&gt;/// Otherwise the operation approaches O(n+m-n) where m is the count of the larger set and n is the&lt;br/&gt;/// smaller set.&lt;br/&gt;/// &amp;lt;/remarks&amp;gt;&lt;br/&gt;/// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;Type of element in each set&amp;lt;/typeparam&amp;gt;&lt;br/&gt;/// &amp;lt;param name=&amp;quot;setA&amp;quot;&amp;gt;A set where each element is of type &amp;lt;typeparamref name=&amp;quot;T&amp;quot;/&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;/// &amp;lt;param name=&amp;quot;setB&amp;quot;&amp;gt;A set where each element is of type &amp;lt;typeparamref name=&amp;quot;T&amp;quot;/&amp;gt;&amp;lt;/param&amp;gt;&lt;br/&gt;/// &amp;lt;param name=&amp;quot;comparer&amp;quot;&amp;gt;&amp;lt;see cref=&amp;quot;IComparer&amp;quot;/&amp;gt; used to sort the sets&amp;lt;/param&amp;gt;&lt;br/&gt;/// &amp;lt;returns&amp;gt;Returns A \ B (-1), the intersection of A and B (0), and B \ A (1)&amp;lt;/returns&amp;gt;&lt;br/&gt;public static IEnumerable&amp;lt;KeyValuePair&amp;lt;T, int&amp;gt;&amp;gt; Membership&amp;lt;T&amp;gt; (IEnumerable&amp;lt;T&amp;gt; sortedSetA, IEnumerable&amp;lt;T&amp;gt; sortedSetB, IComparer&amp;lt;T&amp;gt; comparer) {&lt;br/&gt;    const int onlyA = -1;&lt;br/&gt;    const int both = 0;&lt;br/&gt;    const int onlyB = 1;&lt;br/&gt;&lt;br/&gt;    if (sortedSetA == null)&lt;br/&gt;        throw new ArgumentNullException (&amp;quot;sortedSetA&amp;quot;);&lt;br/&gt;    if (sortedSetB == null)&lt;br/&gt;        throw new ArgumentNullException (&amp;quot;sortedSetB&amp;quot;);&lt;br/&gt;    if (comparer == null)&lt;br/&gt;        throw new ArgumentNullException (&amp;quot;comparer&amp;quot;);&lt;br/&gt;&lt;br/&gt;    IEnumerator&amp;lt;T&amp;gt; enumeratorA = sortedSetA.GetEnumerator ();&lt;br/&gt;    IEnumerator&amp;lt;T&amp;gt; enumeratorB = sortedSetB.GetEnumerator ();&lt;br/&gt;&lt;br/&gt;    bool nextA = enumeratorA.MoveNext ();&lt;br/&gt;    bool nextB = enumeratorB.MoveNext ();&lt;br/&gt;&lt;br/&gt;    // default value for type T&lt;br/&gt;    T a = default (T);&lt;br/&gt;    // default value for type T&lt;br/&gt;    T b = default (T);&lt;br/&gt;&lt;br/&gt;    // if both collections have a value&lt;br/&gt;    if (nextA &amp; nextB) {&lt;br/&gt;        // get current value&lt;br/&gt;        a = enumeratorA.Current;&lt;br/&gt;        // get current value&lt;br/&gt;        b = enumeratorB.Current;&lt;br/&gt;&lt;br/&gt;        do {&lt;br/&gt;            // Compare a to b: is a &amp;lt; b, a == b, or a &amp;gt; b ?&lt;br/&gt;            int val = comparer.Compare (a, b);&lt;br/&gt;            // a == b&lt;br/&gt;            if (val == 0) {&lt;br/&gt;                // return both collections have the value a&lt;br/&gt;                yield return new KeyValuePair&amp;lt;T, int&amp;gt; (a, both);&lt;br/&gt;                // if collection a can move next&lt;br/&gt;                if (nextA = enumeratorA.MoveNext ())&lt;br/&gt;                    // get the next a&lt;br/&gt;                    a = enumeratorA.Current;&lt;br/&gt;                // if collection b can move next&lt;br/&gt;                if (nextB = enumeratorB.MoveNext ())&lt;br/&gt;                    // get the next b&lt;br/&gt;                    b = enumeratorB.Current;&lt;br/&gt;            }&lt;br/&gt;            // a &amp;lt; b&lt;br/&gt;            else if (val &amp;lt; 0) {&lt;br/&gt;                // return only collection a has the value a&lt;br/&gt;                yield return new KeyValuePair&amp;lt;T, int&amp;gt; (a, onlyA);&lt;br/&gt;                // if collection a can move next&lt;br/&gt;                if (nextA = enumeratorA.MoveNext ())&lt;br/&gt;                    // get the next a&lt;br/&gt;                    a = enumeratorA.Current;&lt;br/&gt;            }&lt;br/&gt;            // a &amp;gt; b&lt;br/&gt;            else {&lt;br/&gt;                // return only collection b has the value b&lt;br/&gt;                yield return new KeyValuePair&amp;lt;T, int&amp;gt; (b, onlyB);&lt;br/&gt;                // if collection b can move next&lt;br/&gt;                if (nextB = enumeratorB.MoveNext ())&lt;br/&gt;                    // get the next b&lt;br/&gt;                    b = enumeratorB.Current;&lt;br/&gt;            }&lt;br/&gt;            // loop while there are values for both collections&lt;br/&gt;        } while (nextA &amp; nextB);&lt;br/&gt;    }&lt;br/&gt;    // if collection a has more values&lt;br/&gt;    if (nextA) {&lt;br/&gt;        // return only collection a has the value a&lt;br/&gt;        yield return new KeyValuePair&amp;lt;T, int&amp;gt; (a, onlyA);&lt;br/&gt;        // if collection a can move next&lt;br/&gt;        while (enumeratorA.MoveNext ()) {&lt;br/&gt;            // return only collection a has the value a&lt;br/&gt;            yield return new KeyValuePair&amp;lt;T, int&amp;gt; (enumeratorA.Current, onlyA);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    // if collection b has more values&lt;br/&gt;    else if (nextB) {&lt;br/&gt;        // return only collection b has the value b&lt;br/&gt;        yield return new KeyValuePair&amp;lt;T, int&amp;gt; (b, onlyB);&lt;br/&gt;        // if collection b can move next&lt;br/&gt;        while (enumeratorB.MoveNext ()) {&lt;br/&gt;            // return only collection b has the value b&lt;br/&gt;            yield return new KeyValuePair&amp;lt;T, int&amp;gt; (enumeratorB.Current, onlyB);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=8lFrd_TdbgM:y2FbRw-jusU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=8lFrd_TdbgM:y2FbRw-jusU:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=8lFrd_TdbgM:y2FbRw-jusU:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=8lFrd_TdbgM:y2FbRw-jusU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=8lFrd_TdbgM:y2FbRw-jusU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/8lFrd_TdbgM" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2008/12/10/sequence-membership.html</feedburner:origLink></entry><entry><title>c# Language request for properties</title><category term=".NET" /><category term="c#" /><id>http://george.tsiokos.com/posts/2008/10/7/c-language-request-for-properties.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/iH1cKty9k60/c-language-request-for-properties.html" /><author><name>George Tsiokos</name></author><published>2008-10-07T18:04:36Z</published><updated>2008-10-07T18:04:36Z</updated><content type="html" xml:lang="en-US">&lt;a href="http://msdn.microsoft.com/en-us/library/bb384054.aspx"&gt;Auto-Implemented&lt;/a&gt; properties are great, until you need to implement custom get or set logic. I love the ability to make the field &lt;em&gt;an implementation detail&lt;/em&gt;, until you need to implement the property. &lt;u&gt;What if&lt;/u&gt; you could continue to hide the field, like this:&lt;pre&gt;public string FirstName {&lt;br/&gt;  get {&lt;br/&gt;    // do more stuff, like lazy init the field&lt;br/&gt;    if (field == null)&lt;br/&gt;      field = "Unknown";&lt;br/&gt;    return &lt;strong&gt;field&lt;/strong&gt;;&lt;br/&gt;  }&lt;br/&gt;  set {&lt;br/&gt;    &lt;strong&gt;field&lt;/strong&gt; = &lt;strong&gt;value&lt;/strong&gt;;&lt;br/&gt;  }&lt;br/&gt;}&lt;/pre&gt;A new keyword, &lt;strong&gt;field&lt;/strong&gt;, references the compiler generated property’s backing field. Also, for readonly fields:&lt;pre&gt;public &lt;strong&gt;readonly &lt;/strong&gt;string Id {&lt;br/&gt;  get {&lt;br/&gt;    return &lt;strong&gt;field&lt;/strong&gt;;&lt;br/&gt;  }&lt;br/&gt;  set { // private is implied&lt;br/&gt;    // do more stuff, like don't accept null&lt;br/&gt;    if (value == null)&lt;br/&gt;      value = string.Empty;&lt;br/&gt;    &lt;strong&gt;field&lt;/strong&gt; = &lt;strong&gt;value&lt;/strong&gt;;&lt;br/&gt;  }&lt;br/&gt;}&lt;/pre&gt;Where the property would need to be set in the constructor (like read-only fields) as the backing field would be marked read-only. For simplicity, the implementation would use simple property syntax while the compiled output would involve a read-only field, a truly read-only property and a constructor that executes the property's set body via a static method call each time the field is set in the constructor.&lt;br/&gt;&lt;br/&gt;Please &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=373554"&gt;rate and validate&lt;/a&gt; this sugestion at the MSDN Microsoft Product Feedback Center.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=iH1cKty9k60:oT0_wfI1k7s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=iH1cKty9k60:oT0_wfI1k7s:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=iH1cKty9k60:oT0_wfI1k7s:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=iH1cKty9k60:oT0_wfI1k7s:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=iH1cKty9k60:oT0_wfI1k7s:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/iH1cKty9k60" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2008/10/7/c-language-request-for-properties.html</feedburner:origLink></entry><entry><title>LINQ to SQL produces incorrect TSQL when using UNION or CONCAT</title><category term=".NET" /><category term="Bugs" /><category term="LINQ" /><id>http://george.tsiokos.com/posts/2008/9/10/linq-to-sql-produces-incorrect-tsql-when-using-union-or-conc.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/-er8IC91eg8/linq-to-sql-produces-incorrect-tsql-when-using-union-or-conc.html" /><author><name>George Tsiokos</name></author><published>2008-09-10T20:50:09Z</published><updated>2008-09-10T20:50:09Z</updated><content type="html" xml:lang="en-US">When a LINQ to SQL query contains a Union or Concat with a second query, and the second query references a column twice, a SqlException will occur.&lt;br/&gt;&lt;br/&gt;&lt;pre&gt;var a = from address in dc.Addresses&lt;br/&gt;select new {&lt;br/&gt;ID = address.AddressID,&lt;br/&gt;Address1 = address.AddressLine1,&lt;br/&gt;Address2 = address.AddressLine2,&lt;br/&gt;};&lt;br/&gt;var b = from address in dc.Addresses&lt;br/&gt;select new {&lt;br/&gt;ID = address.AddressID,&lt;br/&gt;Address1 = address.AddressLine1,&lt;br/&gt;Address2 = address.AddressLine1, // notice AddressLine1 repeated&lt;br/&gt;};&lt;br/&gt;var q = a.Take(10).Union (b.Take(10));&lt;br/&gt;q.ToArray ();&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;SqlException: &lt;strong&gt;All the queries in a query expression containing a UNION operator must have the same number of expressions in their select lists.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre&gt;SELECT [t2].[AddressID] AS [ID], [t2].[AddressLine1] AS [Address1], [t2].[AddressLine2] AS [Address2]&lt;br/&gt;FROM (&lt;br/&gt;SELECT TOP (10) [t0].[AddressID], [t0].[AddressLine1], [t0].[AddressLine2]&lt;br/&gt;FROM [Person].[Address] AS [t0]&lt;br/&gt;UNION&lt;br/&gt;SELECT TOP (10) [t1].[AddressID], [t1].[AddressLine1]&lt;br/&gt;FROM [Person].[Address] AS [t1]&lt;br/&gt;) AS [t2]&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;Notice the third SELECT statement is only selecting two columns instead of the required three.&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;Please &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=355734"&gt;rate and validate&lt;/a&gt; this bug at the MSDN Microsoft Product Feedback Center so Microsoft responds with a solution or workaround.&lt;br/&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=-er8IC91eg8:nSF7ZpPLwK4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=-er8IC91eg8:nSF7ZpPLwK4:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=-er8IC91eg8:nSF7ZpPLwK4:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=-er8IC91eg8:nSF7ZpPLwK4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=-er8IC91eg8:nSF7ZpPLwK4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/-er8IC91eg8" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2008/9/10/linq-to-sql-produces-incorrect-tsql-when-using-union-or-conc.html</feedburner:origLink></entry><entry><title>Extending LINQ to SQL</title><category term=".NET" /><category term="LINQ" /><id>http://george.tsiokos.com/posts/2008/9/9/extending-linq-to-sql.html</id><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/george_tsiokos/~3/MgtZuQXaO_Q/extending-linq-to-sql.html" /><author><name>George Tsiokos</name></author><published>2008-09-09T16:15:44Z</published><updated>2008-09-09T16:15:44Z</updated><content type="html" xml:lang="en-US">Last year, Scott Guthrie &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/07/31/linq-to-sql-debug-visualizer.aspx"&gt;stated&lt;/a&gt; “You can actually override the raw SQL that LINQ to SQL uses if you want absolute control over the SQL executed”, but I can’t find documentation describing an extensibility method.&lt;br/&gt;&lt;br/&gt;I would like to modify the following LINQ to SQL query:&lt;br/&gt;&lt;pre&gt;using (NorthwindContext northwind = new NorthwindContext ()) {&lt;br/&gt;    var q = from row in northwind.Customers&lt;br/&gt;            let orderCount = row.Orders.Count ()&lt;br/&gt;            select new {&lt;br/&gt;                row.ContactName,&lt;br/&gt;                orderCount&lt;br/&gt;            };&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Which results in the following TSQL:&lt;br/&gt;&lt;pre&gt;SELECT [t0].[ContactName], (&lt;br/&gt;    SELECT COUNT(*)&lt;br/&gt;    FROM [dbo].[Orders] AS [t1]&lt;br/&gt;    WHERE [t1].[CustomerID] = [t0].[CustomerID]&lt;br/&gt;    ) AS [orderCount]&lt;br/&gt;FROM [dbo].[Customers] AS [t0]&lt;/pre&gt;&lt;br/&gt;To:&lt;br/&gt;&lt;pre&gt;using (NorthwindContext northwind = new NorthwindContext ()) {&lt;br/&gt;    var q = from row in northwind.Customers.With (&lt;br/&gt;                        TableHint.NoLock, TableHint.Index (0))&lt;br/&gt;            let orderCount = row.Orders.With (&lt;br/&gt;                        TableHint.HoldLock).Count ()&lt;br/&gt;            select new {&lt;br/&gt;                row.ContactName,&lt;br/&gt;                orderCount&lt;br/&gt;            };&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;Which &lt;em&gt;would&lt;/em&gt; result in the following TSQL:&lt;br/&gt;&lt;pre&gt;SELECT [t0].[ContactName], (&lt;br/&gt;    SELECT COUNT(*)&lt;br/&gt;    FROM [dbo].[Orders] AS [t1] WITH (HOLDLOCK)&lt;br/&gt;    WHERE [t1].[CustomerID] = [t0].[CustomerID]&lt;br/&gt;    ) AS [orderCount]&lt;br/&gt;FROM [dbo].[Customers] AS [t0] WITH (NOLOCK, INDEX(0))&lt;/pre&gt;&lt;br/&gt;Using:&lt;br/&gt;&lt;pre&gt;public static Table&amp;lt;TEntity&amp;gt; With&amp;lt;TEntity&amp;gt; (&lt;br/&gt;    this Table&amp;lt;TEntity&amp;gt; table,&lt;br/&gt;    params TableHint[] args) where TEntity : class {&lt;br/&gt;&lt;br/&gt;    //TODO: implement&lt;br/&gt;    return table;&lt;br/&gt;}&lt;br/&gt;public static EntitySet&amp;lt;TEntity&amp;gt; With&amp;lt;TEntity&amp;gt; (&lt;br/&gt;    this EntitySet&amp;lt;TEntity&amp;gt; entitySet,&lt;br/&gt;    params TableHint[] args) where TEntity : class {&lt;br/&gt;&lt;br/&gt;    //TODO: implement&lt;br/&gt;    return entitySet;&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;And&lt;br/&gt;&lt;pre&gt;&lt;br/&gt;public class TableHint {&lt;br/&gt;    //TODO: implement&lt;br/&gt;    public static TableHint NoLock;&lt;br/&gt;    public static TableHint HoldLock;&lt;br/&gt;    public static TableHint Index (int id) {&lt;br/&gt;        return null;&lt;br/&gt;    }&lt;br/&gt;    public static TableHint Index (string name) {&lt;br/&gt;        return null;&lt;br/&gt;    }&lt;br/&gt;}&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Using some type of LINQ to SQL extensibility, other than &lt;a href="http://blogs.msdn.com/mattwar/archive/2008/05/04/mocks-nix-an-extensible-linq-to-sql-datacontext.aspx"&gt;this one&lt;/a&gt;. Any ideas?&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Please comment on this question over at &lt;a href="http://stackoverflow.com/questions/62963/how-do-you-extend-linq-to-sql"&gt;StackOverflow.com&lt;/a&gt;&lt;/strong&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MgtZuQXaO_Q:gpmCw28wbmI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MgtZuQXaO_Q:gpmCw28wbmI:I2FUP0JpNAM"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?i=MgtZuQXaO_Q:gpmCw28wbmI:I2FUP0JpNAM" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MgtZuQXaO_Q:gpmCw28wbmI:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/george_tsiokos?a=MgtZuQXaO_Q:gpmCw28wbmI:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/george_tsiokos?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/george_tsiokos/~4/MgtZuQXaO_Q" height="1" width="1"/&gt;</content><feedburner:origLink>http://george.tsiokos.com/posts/2008/9/9/extending-linq-to-sql.html</feedburner:origLink></entry></feed>
