<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.0.5" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Bits.Bytes.</title>
	<link>http://thinkersroom.com/bytes</link>
	<description>2+2=5, for large values of 2</description>
	<pubDate>Fri, 16 May 2008 08:42:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.5</generator>
	<language>en</language>
			<item>
		<title>Borland/Inprise/Codegear</title>
		<link>http://thinkersroom.com/bytes/2008/05/16/borlandinprisecodegear/</link>
		<comments>http://thinkersroom.com/bytes/2008/05/16/borlandinprisecodegear/#comments</comments>
		<pubDate>Fri, 16 May 2008 08:42:55 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Software</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2008/05/16/borlandinprisecodegear/</guid>
		<description><![CDATA[Well, it&#8217;s old news by now that CodeGear has been brought by Embarcadero technologies.
Now, while established CodeGear staff&#160; sound very chipper about it, to me it is just the death knell sound of the kicks of a dying horse. CodeGear is the the quintessential example of a company that never misses an opportunity to miss [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it&#8217;s old news by now that CodeGear has been brought by Embarcadero technologies.<br />
Now, while established CodeGear staff&nbsp; sound very chipper about it, to me it is just the death knell sound of the kicks of a dying horse. CodeGear is the the quintessential example of a company that never misses an opportunity to miss an opportunity. (BTW I&#8217;ve been a Delphi fan for years, and still have my trusty Delphi 7)<br />
For a while there after it was spun off by Borland I thought that it might just turn the corner but alas! Some of the things that make me wonder are</p>
<h2>The Delphi Brand Confusion</h2>
<p>Previously Delphi was pretty much the equivalent of VB brand-wise. It was the IDE and the language (although Object Pascal is strictly speaking the actual language, but decades of referring to it as Delphi has cast it in stone). But now confusion abounds in the CodeGear camp. Delphi is the language and the IDE. And there is Delphi for AS400. So far so good. But now there is Delphi for PHP. So Delphi is perhaps the IDE only. But to add even more confusion there is no Delphi for Ruby. It is called 3rdRail.</p>
<h2>Blackfish</h2>
<p>CodeGear have produced what seems like a pretty solid embeddable database engine, Blackfish. Besides being SQL standards compliant it allows you to write procedures and triggers in Java and .NET, a far cry from SQL Compact Edition. Now, perhaps its just me but I can&#8217;t seem to find out if you can get it without having to buy Delphi or any other CodeGear product. Say it ain&#8217;t so!</p>
<h2>Musical Chairs</h2>
<p>The uncertainty about the company never seems to go away. After the name changes Borland-Inprise-Borland-CodeGear, the almost sale, then the spin off and now the acquisition, one wonders what lies next. This uncertainty is not doing anything for a dwindling market share and brand value
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2008/05/16/borlandinprisecodegear/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Happy(?) New Year</title>
		<link>http://thinkersroom.com/bytes/2008/01/07/happy-new-year-2/</link>
		<comments>http://thinkersroom.com/bytes/2008/01/07/happy-new-year-2/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 14:10:52 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Uncategorized</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2008/01/07/happy-new-year-2/</guid>
		<description><![CDATA[First the good news. I was re-awarded my MVP status for the third year running. Needless to say, I am pretty chuffed.
I&#8217;ve gotten a lot of encouraging feedback about the feed reader. Contrary to popular belief, work has not stopped. In fact I will have a feature complete version within a fortnight or so. I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>First the good news. I was <a href="http://mvp.support.microsoft.com/Default.aspx">re-awarded my MVP status</a> for the third year running. Needless to say, I am pretty chuffed.</p>
<p>I&#8217;ve gotten a lot of encouraging feedback about the feed reader. Contrary to popular belief, work has not stopped. In fact I will have a feature complete version within a fortnight or so. I&#8217;ve been very tied up in an number of things, chief of which is a very <a href="http://www.thinkersroom.com/blog">turbulent political situation in my country Kenya</a> that understandably had distracted me and then some. For details see my other blog.</p>
<p>Here&#8217;s to an excellent 2008!
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2008/01/07/happy-new-year-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Huh?</title>
		<link>http://thinkersroom.com/bytes/2007/12/01/huh/</link>
		<comments>http://thinkersroom.com/bytes/2007/12/01/huh/#comments</comments>
		<pubDate>Sat, 01 Dec 2007 13:03:33 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Reflections</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/12/01/huh/</guid>
		<description><![CDATA[ 
They&#8217;ve got guts, I&#8217;ll give them that &#8230;.
]]></description>
			<content:encoded><![CDATA[<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="648" alt="blockdelete" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/12/blockdelete.gif" width="630" border="0"> </p>
<p>They&#8217;ve got guts, I&#8217;ll give them that &#8230;.</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/12/01/huh/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building A Feed Reader #3: Downloading Feeds</title>
		<link>http://thinkersroom.com/bytes/2007/11/06/building-a-feed-reader-3-downloading-feeds/</link>
		<comments>http://thinkersroom.com/bytes/2007/11/06/building-a-feed-reader-3-downloading-feeds/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 15:59:11 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>C#</category>

		<category>Lessons</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/11/06/building-a-feed-reader-3-downloading-feeds/</guid>
		<description><![CDATA[Welcome back. After taking a look at understanding the problem, today&#160;O will discuss some of the issues to do with connectivity. But first:
Progress As Of Today
If I do say so myself, I have been VERY BUSY working on this. It is beginning to take shape and then some.
New Icons
 
Preliminary UI For blogs &#38; smart [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome back. After taking a look at understanding the problem, today&nbsp;O will discuss some of the issues to do with connectivity. But first:</p>
<h2>Progress As Of Today</h2>
<p>If I do say so myself, I have been VERY BUSY working on this. It is beginning to take shape and then some.</p>
<h3>New Icons</h3>
<p><img alt="icons" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/icons.gif"> </p>
<h3>Preliminary UI For blogs &amp; smart feeds</h3>
<p><img alt="foldersandfeeds" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/foldersandfeeds.gif"> </p>
<p>Smart feeds will be searches or watches for particular key words in all subscribed feeds</p>
<h3>Marking items as read and unread</h3>
<p><img alt="readandunread" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/readandunread.gif"> </p>
<p>Less Laziness</p>
<p><img alt="lazy" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/lazy.gif"> </p>
<p>Don&#8217;t you hate it when you see the following: <em>1 Message(s) unread?</em> That&#8217;s laziness right there. LAZINESS!</p>
<h3>Tags</h3>
<p><img alt="tagcreation" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/tagcreation.gif"> </p>
<p>You can create your own tags and then apply them to articles. Since there can be dozens of tags, a way to force you to organize yourself is to use what I&#8217;ll call quick tags. What are quick tags? Simply tags that you decide you will use more often then most. They will appear in the main UI as follows:</p>
<p><img alt="quicktags" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/quicktags.gif"> </p>
<h3>Search</h3>
<p>The search on the main UI is now functional</p>
<p><img alt="searchui" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/searchui.gif"> </p>
<p>Hitting enter pops up this screen</p>
<p><img alt="results" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/results.gif"> </p>
<p>As you can see, the article text, title, categories, authors and tags are used in the search</p>
<h3>Click Through Searches</h3>
<p>A particularly handy feature is the ability to click on an article&#8217;s categories and tags and immediately get a list of other articles with the same category&nbsp;or tag</p>
<p><img alt="clickthrough" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/clickthrough.gif"> </p>
<p>Clicking on a category link will popup the link below</p>
<p><img alt="categoryclick" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/categoryclick.gif"> </p>
<p>Clicking&nbsp; a tag link will popup the link below</p>
<p><img alt="tagclick" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/tagclick.gif"> </p>
<h3>Task Area Menu</h3>
<p>I&#8217;ve added support to display the reader only in the task area (configurable from the settings). See the <a href="http://thinkersroom.com/bytes/2007/11/01/building-a-feed-reader-2-understanding-the-problems/">last issue</a> for details</p>
<p><img alt="taskarea" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/taskarea.gif"> </p>
<h2>Lesson For Today: Connectivity</h2>
<p>The very first problem is getting the raw XML feeds, identifying them and then as appropriate interpreting them for storage and display.</p>
<h3>Identifying &amp; Downloading Feeds</h3>
<p>Identifying the feed type (ATOM, RSS, RSD, etc) Ideally should be something that you do once. So I identify the feed type when you subscribe for the first time. How?</p>
<p>As it so happens the Argotic Framework has a SyndicationDiscovery class that, surprise surprise, discovers a whole lot of information from a feed. It is especially functional because it has LocateEndpoints method that&nbsp;given a URL it will determine all the RSS feeds that can be subscribed to on that particular URL.</p>
<p>The relevant code is as follows:</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre><span class="lnum">   2:</span> <span class="rem">//    Determine the feed format from a given URL</span></pre>
<pre class="alt"><span class="lnum">   3:</span> <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre><span class="lnum">   4:</span> Uri uri                     = <span class="kwrd">new</span> Uri(<span class="str">&#8220;http://thinkersroom.com/bytes/&#8221;</span>);</pre>
<pre class="alt"><span class="lnum">   5:</span> SyndicationFormat format    = SyndicationDiscovery.DetermineSyndicationFormat(uri);</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>The first time I ran this code it failed spectacularly. Why? Because the <a href="http://www.codeplex.com/Argotic">Argotic Framework</a> assumes a direct connection to the Internet! Now that right there is a problem for those of us that are behind proxy servers!</p>
<p>Digging around the source led to the discovery that it is peppered with code like this:</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre><span class="lnum">   2:</span> <span class="rem">//    Create web client to download feed data</span></pre>
<pre class="alt"><span class="lnum">   3:</span> <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre><span class="lnum">   4:</span> <span class="kwrd">using</span>(WebClient webClient = <span class="kwrd">new</span> WebClient())</pre>
<pre class="alt"><span class="lnum">   5:</span> {</pre>
<pre><span class="lnum">   6:</span>    <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre class="alt"><span class="lnum">   7:</span>    <span class="rem">//    Apply security credentials if available</span></pre>
<pre><span class="lnum">   8:</span>    <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre class="alt"><span class="lnum">   9:</span>    <span class="kwrd">if</span>(<span class="kwrd">this</span>.Settings != <span class="kwrd">null</span> &amp;&amp; <span class="kwrd">this</span>.Settings.Credentials != <span class="kwrd">null</span>)</pre>
<pre><span class="lnum">  10:</span>    {</pre>
<pre class="alt"><span class="lnum">  11:</span>        webClient.Credentials   = <span class="kwrd">this</span>.Settings.Credentials;</pre>
<pre><span class="lnum">  12:</span>    }</pre>
<pre class="alt"><span class="lnum">  13:</span> &nbsp;</pre>
<pre><span class="lnum">  14:</span>    <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre class="alt"><span class="lnum">  15:</span>    <span class="rem">//    Download feed data</span></pre>
<pre><span class="lnum">  16:</span>    <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre class="alt"><span class="lnum">  17:</span>    <span class="kwrd">byte</span>[] data = webClient.DownloadData(sourceAsUri);</pre>
<pre><span class="lnum">  18:</span> &nbsp;</pre>
<pre class="alt"><span class="lnum">  19:</span>    <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre><span class="lnum">  20:</span>    <span class="rem">//    Load syndication feed using created stream</span></pre>
<pre class="alt"><span class="lnum">  21:</span>    <span class="rem">//&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></pre>
<pre><span class="lnum">  22:</span>    <span class="kwrd">this</span>.Load(<span class="kwrd">new</span> MemoryStream(data));</pre>
<pre class="alt"><span class="lnum">  23:</span> }</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>This will fail every time if you are behind a proxy server. Fixing it is trivial enough. Since the <a href="http://www.codeplex.com/Argotic">Argotic</a> code is peppered with such code, a utility function to correctly build a WebCllient is needed</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">public</span> <span class="kwrd">static</span> WebClient GetClient(WebProxy proxy)</pre>
<pre><span class="lnum">   2:</span> {</pre>
<pre class="alt"><span class="lnum">   3:</span>     <span class="rem">//</span></pre>
<pre><span class="lnum">   4:</span>     <span class="rem">// Create the web client</span></pre>
<pre class="alt"><span class="lnum">   5:</span>     <span class="rem">//</span></pre>
<pre><span class="lnum">   6:</span>     WebClient webClient = <span class="kwrd">new</span> WebClient();</pre>
<pre class="alt"><span class="lnum">   7:</span>     <span class="rem">//</span></pre>
<pre><span class="lnum">   8:</span>     <span class="rem">//Add a header to identify ourselves</span></pre>
<pre class="alt"><span class="lnum">   9:</span>     <span class="rem">//</span></pre>
<pre><span class="lnum">  10:</span>     webClient.Headers.Add(<span class="str">&#8220;user-agent&#8221;</span>, <span class="str">&#8220;FeedCruncher&#8221;</span>);</pre>
<pre class="alt"><span class="lnum">  11:</span>     <span class="rem">//</span></pre>
<pre><span class="lnum">  12:</span>     <span class="rem">//Assing the proxy where applicable</span></pre>
<pre class="alt"><span class="lnum">  13:</span>     <span class="rem">//</span></pre>
<pre><span class="lnum">  14:</span>     <span class="kwrd">if</span> (proxy != <span class="kwrd">null</span>)</pre>
<pre class="alt"><span class="lnum">  15:</span>         webClient.Proxy = proxy;</pre>
<pre><span class="lnum">  16:</span>     <span class="kwrd">return</span> webClient;</pre>
<pre class="alt"><span class="lnum">  17:</span> }</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>How about the proxy that&#8217;s being passed then?</p>
<p>This one is constructed by the client based on the configured user settings. Here is the code (I&#8217;m writing the UI itself in VB.NET, and the logic in C#. Why? Because I wondered if I could!</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">If</span> My.Settings.UseProxy <span class="kwrd">Then</span></pre>
<pre><span class="lnum">   2:</span>     <span class="rem">&#8216;</span></pre>
<pre class="alt"><span class="lnum">   3:</span>     <span class="rem">&#8216; Create a web proxy</span></pre>
<pre><span class="lnum">   4:</span>     <span class="rem">&#8216;</span></pre>
<pre class="alt"><span class="lnum">   5:</span>     <span class="kwrd">Dim</span> proxy <span class="kwrd">As</span> WebProxy = <span class="kwrd">Nothing</span></pre>
<pre><span class="lnum">   6:</span>     <span class="kwrd">If</span> My.Settings.ProxyAuthentication <span class="kwrd">Then</span></pre>
<pre class="alt"><span class="lnum">   7:</span>         <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">   8:</span>         <span class="rem">&#8216; Create network credential for authentication</span></pre>
<pre class="alt"><span class="lnum">   9:</span>         <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  10:</span>         <span class="kwrd">Dim</span> nc <span class="kwrd">As</span> <span class="kwrd">New</span> NetworkCredential(My.Settings.Username, My.Settings.Password, My.Settings.Domain)</pre>
<pre class="alt"><span class="lnum">  11:</span>         <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  12:</span>         <span class="rem">&#8216; Create web proxy with overload for network credentials</span></pre>
<pre class="alt"><span class="lnum">  13:</span>         <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  14:</span>         proxy = <span class="kwrd">New</span> WebProxy(<span class="kwrd">String</span>.Format(<span class="str">&#8220;{0}:{1}&#8221;</span>, My.Settings.Host, My.Settings.Port), <span class="kwrd">True</span>, _</pre>
<pre class="alt"><span class="lnum">  15:</span>         Regex.Split(My.Settings.ByPassAddresses, <span class="str">&#8220;;|,&#8221;</span>), nc)</pre>
<pre><span class="lnum">  16:</span>     <span class="kwrd">Else</span></pre>
<pre class="alt"><span class="lnum">  17:</span>         <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  18:</span>         <span class="rem">&#8216; Create web proxy without overload for network credentials</span></pre>
<pre class="alt"><span class="lnum">  19:</span>         <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  20:</span>         proxy = <span class="kwrd">New</span> WebProxy(<span class="kwrd">String</span>.Format(<span class="str">&#8220;{0}:{1}&#8221;</span>, My.Settings.Host, My.Settings.Port), <span class="kwrd">True</span>, _</pre>
<pre class="alt"><span class="lnum">  21:</span>         Regex.Split(My.Settings.ByPassAddresses, <span class="str">&#8220;;|,&#8221;</span>))</pre>
<pre><span class="lnum">  22:</span>     <span class="kwrd">End</span> <span class="kwrd">If</span></pre>
<pre class="alt"><span class="lnum">  23:</span>     <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  24:</span>     <span class="rem">&#8216; Return our proxy</span></pre>
<pre class="alt"><span class="lnum">  25:</span>     <span class="rem">&#8216;</span></pre>
<pre><span class="lnum">  26:</span>     <span class="kwrd">Return</span> proxy</pre>
<pre class="alt"><span class="lnum">  27:</span> <span class="kwrd">Else</span></pre>
<pre><span class="lnum">  28:</span>     <span class="rem">&#8216;</span></pre>
<pre class="alt"><span class="lnum">  29:</span>     <span class="rem">&#8216; We don&#8217;t need a proxy. Return nothing</span></pre>
<pre><span class="lnum">  30:</span>     <span class="rem">&#8216;</span></pre>
<pre class="alt"><span class="lnum">  31:</span>     <span class="kwrd">Return</span> <span class="kwrd">Nothing</span></pre>
<pre><span class="lnum">  32:</span> <span class="kwrd">End</span> If</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>And so, our connectivity issue is sorted.</p>
<p>The DetermineSyndicationFormat returns an enumeration. Once you know this you can correctly download the appropriate feed type using code like this:</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> SyndicationFormat sf = SyndicationDiscovery.DetermineSyndicationFormat(<span class="kwrd">new</span> Uri(URL), proxy);</pre>
<pre><span class="lnum">   2:</span> <span class="kwrd">switch</span> (sf)</pre>
<pre class="alt"><span class="lnum">   3:</span> {</pre>
<pre><span class="lnum">   4:</span>     <span class="kwrd">case</span> SyndicationFormat.Rss:</pre>
<pre class="alt"><span class="lnum">   5:</span>         RssFeed rfeed = RssFeed.Create(<span class="kwrd">new</span> Uri(URL), proxy);</pre>
<pre><span class="lnum">   6:</span>         myFeed.Type = FeedType.RSS;</pre>
<pre class="alt"><span class="lnum">   7:</span>         myFeed.SiteURL = rfeed.Channel.Link.OriginalString;</pre>
<pre><span class="lnum">   8:</span>         myFeed.FeedURL = URL;</pre>
<pre class="alt"><span class="lnum">   9:</span>         myFeed.Name = rfeed.Channel.Title;</pre>
<pre><span class="lnum">  10:</span>         myFeed.Header = rfeed.Header;</pre>
<pre class="alt"><span class="lnum">  11:</span>         myFeed.Description = rfeed.Channel.Description;</pre>
<pre><span class="lnum">  12:</span>         myFeed.LastUpdated = rfeed.Channel.LastBuildDate;</pre>
<pre class="alt"><span class="lnum">  13:</span>         myFeed.Generator = rfeed.Channel.Generator;</pre>
<pre><span class="lnum">  14:</span>         <span class="kwrd">foreach</span> (RssItem item <span class="kwrd">in</span> rfeed.Channel.Items)</pre>
<pre class="alt"><span class="lnum">  15:</span>         {</pre>
<pre><span class="lnum">  16:</span>             FeedItem myFeedItem = <span class="kwrd">new</span> FeedItem(item.Link.OriginalString, item.Title, item.Description, item.PublicationDate, item.Guid.Value, <span class="kwrd">false</span>);</pre>
<pre class="alt"><span class="lnum">  17:</span>             myFeedItem.FeedID = myFeed.FeedID;</pre>
<pre><span class="lnum">  18:</span>             <span class="kwrd">foreach</span>(RssCategory cat <span class="kwrd">in</span> item.Categories)</pre>
<pre class="alt"><span class="lnum">  19:</span>                 myFeedItem.Categories.Add(<span class="kwrd">new</span> Category(cat.Value));</pre>
<pre><span class="lnum">  20:</span>             myFeed.Items.Add(myFeedItem);</pre>
<pre class="alt"><span class="lnum">  21:</span>             myFeed.Guids.Add(item.Guid.Value);</pre>
<pre><span class="lnum">  22:</span>         }</pre>
<pre class="alt"><span class="lnum">  23:</span>         <span class="kwrd">break</span>;</pre>
<pre><span class="lnum">  24:</span>     <span class="kwrd">case</span> SyndicationFormat.Atom:</pre>
<pre class="alt"><span class="lnum">  25:</span>         <span class="rem">//</span></pre>
<pre><span class="lnum">  26:</span>         <span class="rem">// Same logic but for the ATOM format</span></pre>
<pre class="alt"><span class="lnum">  27:</span>         <span class="rem">//</span></pre>
<pre><span class="lnum">  28:</span> }</pre>
<pre class="alt"><span class="lnum">  29:</span> <span class="kwrd">return</span> myFeed;</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>To store the results, I use plain old C# objects to mirror a blog (Feed) and its items (FeedItems)</p>
<p>So, as you can see the bulk of the work is done by the <a href="http://www.codeplex.com/Argotic">Argotic Framework</a>.</p>
<h3>Conditional Get</h3>
<p>When it comes to feed readers, an essential consideration is saving bandwidth. The most common way is to only fetch a feed if it has been updated since the last check. This is implemented on the http conditional-get method, and in this manner we can save quite a bit of bandwidth.</p>
<p>However the build that I believe to be the latest, 2.0,&nbsp;always returns true for the HasChanges property. I&#8217;ve been looking for the code for a while but it&#8217;s not clear to me&nbsp;how the headers are set in the conditional get request. Hmm.</p>
<p>Now what do we do once we have this data in our custom objects? Why save it of course.</p>
<p><strong>Stay tuned for Episode 4: Persisting to Database</strong></p>
<p>&nbsp;</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fthinkersroom.com%2fbytes%2f2007%2f11%2f06%2fbuilding-a-feed-reader-3-downloading-feeds%2f"><img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fthinkersroom.com%2fbytes%2f2007%2f11%2f06%2fbuilding-a-feed-reader-3-downloading-feeds%2f" border="0"></a>
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/11/06/building-a-feed-reader-3-downloading-feeds/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building A Feed Reader #2: Understanding The Problem(s)</title>
		<link>http://thinkersroom.com/bytes/2007/11/01/building-a-feed-reader-2-understanding-the-problems/</link>
		<comments>http://thinkersroom.com/bytes/2007/11/01/building-a-feed-reader-2-understanding-the-problems/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 12:21:52 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Software</category>

		<category>Lessons</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/11/01/building-a-feed-reader-2-understanding-the-problems/</guid>
		<description><![CDATA[Welcome back&#160;to this series where I share my experiences in building a feed reader.
To keep you interested, and prove that I&#8217;m not just talking, what I&#8217;ll be doing is showing you where I&#8217;ve reached so far and then go on to the meat and potatoes
Progress As Of Today
Grouping
Feed Cruncher can now group articles by Date [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://thinkersroom.com/bytes/2007/10/31/building-a-feed-reader-episode-one/">Welcome back</a>&nbsp;to this series where I share my experiences in building a feed reader.</p>
<p>To keep you interested, and prove that I&#8217;m not just talking, what I&#8217;ll be doing is showing you where I&#8217;ve reached so far and then go on to the meat and potatoes</p>
<h2>Progress As Of Today</h2>
<h3>Grouping</h3>
<p>Feed Cruncher can now group articles by Date and By Month, which you toggle with buttons on the menu bar</p>
<p><img alt="grouping" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/grouping.gif"> </p>
<h3>Grouping By Day</h3>
<p>This groups all items by day, so you can see at a glance all articles from a particular day. This is good for blogs that have lots of daily posts. And believe me there are many!</p>
<p><img alt="GroupingDay" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/GroupingDay.gif"> </p>
<h3>Grouping By Month</h3>
<p>This group all items by month, so you can see at a glance all articles for a particular month. This is good for blogs that post less frequently</p>
<p><img alt="GroupingMonth" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/GroupingMonth.gif"> </p>
<h3>Settings</h3>
<p>The application can now persist settings</p>
<p><img alt="Settings1" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/Settings1.gif"> </p>
<p><img alt="Settings2" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/Settings2.gif"> </p>
<h2>Lesson For Today: Understanding The Problem</h2>
<p>So, <a href="http://thinkersroom.com/bytes/2007/10/31/building-a-feed-reader-episode-one/">as I mentioned yesterday</a>, I found myself bemoaning the inability to find a good reader. So I decided to write my own.</p>
<p>Deciding to write your own does not necessarily mean starting from scratch with File -&gt; New Project. There must be some readers with source available. As it turns out there are two that I know of: <a href="http://rssbandit.org">RSS Bandit</a> and <a href="http://www.rssowl.org">RSSOwl</a>.</p>
<p>RSSOwl I dismissed as a non starter because it is written in Java. My last brush with Java was many years ago and describing myself as rusty would be flattering myself.</p>
<p>Which leaves RSS Bandit. I used to use it a while back until the horrifying feature creep that <a href="http://www.codinghorror.com/blog/archives/000973.html">Jeff Atwood speaks so eloquently about</a> began to creep in. Newsgator? NNTP? It also uses Infragistics for UI, which is yet another huge library. A bit much if all you need is a listview and a treeview. And every time I used it it would seem to fool itself into thinking it was SQL Server 2008 and begin taking all the memory it could get its hands on!</p>
<p>Ok, ok, those are lame excuses. RSS Bandit is excellent software but it does not do some&nbsp;of the things that I consider crucial.&nbsp;I also don&#8217;t agree entirely with some of the design decisions that were taken. Eventually I decided to start off with a clean slate, make all the choices and design decisions myself and build the freed reader!</p>
<p>So, that is the problem.</p>
<p>Build A Feed Reader</p>
<p>From experience and education, and lots of reading, I have come round to the school of thought that all big problems (including Wars In Iraq, Inflation, Reality TV, etc) are actually composed of many smaller problems.</p>
<p>Solve these small problems and the big ones automatically get solved.</p>
<p>So what are the small problems in building a Feed Reader</p>
<h2>Problem Definition</h2>
<ol>
<li>Knowing where feeds can be found, or discovering new feeds to subscribe
<li>Storing these subscriptions, and allowing user to manage them
<li>Connecting to remote websites with subscribed&nbsp;RSS feeds
<li>Downloading RSS feeds from the Internet
<li>Interpreting these feeds
<li>Storing these feeds
<li>Displaying these feeds to the user
<li>Allowing user to mark as read, tag and otherwise manipulate these items
<li>Storing these changes
<li>Updating feeds
<li>Allowing user to search all these
<li>Other features e.g. search, export, etc</li>
</ol>
<p>Looking closely at the problem definition, we can tentatively abstract the following as the core functionality</p>
<ol>
<li>Download Feeds (Connectivity &amp; Interpretation)
<li>Store them (Storage)
<li>Display to the user (Interface)</li>
</ol>
<h4>Download Feeds (Connectivity &amp; Interpretation)</h4>
<p>Here we will need to connect to a website, download its RSS feed and then interpret it. Why interpret? Because there are several formats:</p>
<ul>
<li>Atom
<li>RSS
<li>OpenSearch
<li>RSD</li>
</ul>
<p>At first I was considering doing this using a WebClient to download the data and a lot of XML and Regular Expressions to identify and parse the feeds until I stumbled upon the <a href="http://www.codeplex.com/Argotic">Argotic Syndication Framework</a>. Brilliant does not begin to describe it. It does exactly what I wanted and then some.</p>
<p>In the course of using it I have found some quirks and some bugs but the guys get 11 points out of 10 for the excellent job. A third of my battle is won!</p>
<h4>Store Them (Storage)</h4>
<p>The next problem was storage. Basically there are three options:</p>
<ol>
<li>Store the actual XML on disk
<li>Store the actual XML in a database
<li>Interpret the feed and split it into its constituent parts&nbsp;and store those in the database</li>
</ol>
<p>Storage on disk is the least attractive option for a couple of reasons</p>
<ol>
<li>There will eventually be a performance hit after getting a lot of files on disk to process one after another
<li>Search will be very difficult, if not impossible
<li>It is bound to be a wasteful strategy because if an entry is added you download the old entries all over again
<li>Some other reason I can&#8217;t remember at this point</li>
</ol>
<p>Which leaves storage in a database. Which opens another can of worms &#8230; which database to use?</p>
<p>To be lightweight clearly we need something &#8230; well, light. Which knocks out of the running things like SQL Server Express. What is lighter than that? Microsoft Jet. Which leaves me very uncomfortable. I&#8217;ve never fully trusted jet after getting my fingers burnt several times. Is there something even lighter that can run in process?</p>
<p>Turns out there are several. <a href="http://www.microsoft.com/sql/editions/compact/default.mspx">SQL Server Compact Edition</a>, <a href="http://www.vistadb.net/">VistaDB</a>, <a href="http://www.codegear.com/products/blackfish">CodeGear Blackfish</a>. Since I am fiscally constrained, VistaDB and Blackfish need not apply. So SQL Server Compact Edition it is. Although I would have preferred to use either of the latter because they support a greater SQL dialect, triggers, stored procedures and views. There&#8217;s also <a href="http://www.sqlite.org/index.html">SQL Lite</a>, but&nbsp;this is a good an exercise as any to try out SQL CE before I deploy it for some real projects that are coming up. </p>
<p>Reading some of the white papers about SQL Compact Edition fills me with admiration. Some people in Microsoft are truly masters of spin. It is only a brave man who will attempt to explain how lack of triggers, views and procedures is a good thing! Maybe its just me but I don&#8217;t find the <a href="http://download.microsoft.com/download/7/f/c/7fc20778-4e2e-4944-b432-ed74b404e542/sqlservercompactdatasheet_final.doc">arguments</a> as to <a href="http://www.microsoft.com/sql/editions/compact/ssceoverview.mspx">lack o</a>f these things <a href="http://www.microsoft.com/sql/editions/compact/sscecomparison.mspx">convincing</a> in the least.</p>
<p>But I digress. Once settling on that and doing some research, it seemed that it addition to what&#8217;s missing, it actually stores XML as NText, which knocks out option 2. </p>
<p>Which means I must interpret the RSS feeds, extract the content and then store it, which on reflection sounds like a pretty solid solution. Why? I can search quickly using normal database expressions. I can do things like sort on various fields &#8212; date created, author, etc. And it won&#8217;t be too hard to generate XML should I need to</p>
<h4>Display To The User (Interface)</h4>
<p>This is the final part &#8230; displaying to the user. </p>
<p>Since I want the application to be desktop based, Windows Forms is the obvious choice. I could do WPF but I&#8217;m pressed for time and WPF might be an overkill for this. Displaying the feeds out to be simple enough. All we need is to load the feeds from the database at startup and populate the tree view on the left. Then when you click on a feed populate the listview on the right. Then when you click on an item, display its content in the WebBrowser pane below.</p>
<p>Here is a mockup</p>
<p><img alt="mockup" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/11/mockup.gif"> </p>
<p>This, as it turns out, despite sounding simple, is a bit more complicated that I thought</p>
<p><strong>Stay tuned for Episode 3: Downloading Feeds</strong></p>
<p> <a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fthinkersroom.com%2fbytes%2f2007%2f11%2f01%2fbuilding-a-feed-reader-2-understanding-the-problems%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fthinkersroom.com%2fbytes%2f2007%2f11%2f01%2fbuilding-a-feed-reader-2-understanding-the-problems%2f" border="0" alt="kick it on DotNetKicks.com"></a>
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/11/01/building-a-feed-reader-2-understanding-the-problems/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Building A Feed Reader: Episode One</title>
		<link>http://thinkersroom.com/bytes/2007/10/31/building-a-feed-reader-episode-one/</link>
		<comments>http://thinkersroom.com/bytes/2007/10/31/building-a-feed-reader-episode-one/#comments</comments>
		<pubDate>Wed, 31 Oct 2007 14:55:58 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Software</category>

		<category>Lessons</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/10/31/building-a-feed-reader-episode-one/</guid>
		<description><![CDATA[I depend heavily on RSS. To find out what&#8217;s going on in general and in the technology sector. I have subscribed literally to hundreds of feeds. Needless to say, I need a tool to better help me manage all this information.
For a very long time I have been looking for a good RSS Feed reader. [...]]]></description>
			<content:encoded><![CDATA[<p>I depend heavily on RSS. To find out what&#8217;s going on in general and in the technology sector. I have subscribed literally to hundreds of feeds. Needless to say, I need a tool to better help me manage all this information.</p>
<p>For a very long time I have been looking for a good RSS Feed reader. What do I mean by a good RSS Feed Reader?</p>
<ul>
<li><strong>Desktop application</strong>. Google Reader / Bloglines / NewsGator need not apply!
<li><strong>Stable</strong>. &#8216;Nuff said.
<li><strong>Fast</strong>. &#8216;Nuff said.
<li><strong>Portable</strong>. Can carry around on my flash disk. And no, synchronization with NewsGator/Bloglines will not do
<li><strong>Lightweight</strong>.
<li>Newspaper View <strong>AND</strong> Item View
<li><strong>Offline</strong> Reading.
<li>Quick <strong>Search</strong>, integrated right into the main UI.
<li><strong>Smart</strong>/Search Folders.
<li>Support for downloading <strong>enclosures</strong>.
<li><strong>Filters</strong> to allow view of Read/Unread/All messages
<li><strong>Groups items</strong> by custom groups &#8212; Day, Month, Category, etc
<li>Allows me to <strong>flag</strong> articles to return to later
<li>Allows me to <strong>tag</strong> articles with my own tags.
<li>Can <strong>easily customize</strong> display with styles and themes.
<li>Exports content to <strong>PDF</strong>.
<li>Works quietly in the <strong>background</strong> and notifies me via desktop alerts.
<li>Can <strong>discover</strong> feeds on web pages.
<li><strong>Keeps track</strong> of update frequency, allowing me to purge feeds that are rarely updated.
<li>Allows me to have <strong>custom folders</strong> to store feeds.
<li>Allows me to <strong>nest</strong> the custom folders.
<li>Displays links to <strong>comments</strong> (where available)
<li><strong>Differentiates</strong> read from unread items
<li>Offers various <strong>reports</strong> and <strong>charts</strong>.
<ul>
<li>Feeds per folder
<li>Subscribed Feeds
<li>Most&nbsp;recently &nbsp;updated feeds
<li>Most popular generator software (blogger / wordpress / movable type /&nbsp;feed burner / etc.)
<li>Tags per feed
<li>Tags for all feeds</li>
</ul>
<li>Saves bandwidth by making use of <strong>conditional get</strong>.
<li>Imports and exports to <strong>OPML</strong></li>
</ul>
<p>&nbsp;</p>
<p>Believe you me I have looked high and looked low. I have tried them all out. <a href="http://www.newsgator.com">FeedDemon</a>, <a href="http://www.feedreader.com">FeedReader</a>, <a href="http://snarfware.com/">Snarfware</a>, <a href="http://www.rssowl.org">RSSOwl</a>, <a href="http://www.curiostudio.com/">GreatNews</a>, <a href="http://www.sharpreader.net/">SharpReader</a>, <a href="http://www.rssbandit.org">RSSBandit</a>, <a href="http://www.rssreader.com/">RSS Reader</a>, <a href="http://www.cincomsmalltalk.com/BottomFeeder/">BottomFeeder</a>,&nbsp; <a href="http://www.microsoft.com/office">Outlook</a>, <a href="http://www.jetbrains.com/omea">Omea</a>, <a href="http://www.microsoft.com/ie">Internet Explorer</a>, <a href="http://mozilla.org">Firefox</a>, <a href="http://www.mozilla.org">Thunderbird</a>,&nbsp;<a href="http://www.opera.com">Opera</a> and countless others I forget right now.</p>
<p>They all have something or the other missing from the list, and every time I button down and pick one, after a while I come to resent what it is that I have sacrificed.</p>
<p>And so I did the only logical thing.</p>
<p>I started writing my own.</p>
<p>It has been much easier than I thought, to tell the truth. The .NET Framework is very powerful and Visual Studio 2005 is an excellent tool for development and debugging. In a couple of days I&#8217;ve been able to put together the skeleton of the application. Here are some screen shots of what is currently working so far</p>
<h3>Main Screen</h3>
<p><img alt="mainwindow" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/mainwindow.gif"> </p>
<h3>Subscribing To A Feed</h3>
<p><img alt="subscribing" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/subscribing.gif"> </p>
<h3>Discovering Feeds</h3>
<p><img alt="feeddiscovery" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/feeddiscovery.gif"> </p>
<h3>Folder Management</h3>
<p><img alt="foldermanagment" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/foldermanagment.gif"> </p>
<h3>Feed Properties</h3>
<p><img alt="FeedProperties" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/FeedProperties.gif"> </p>
<p>&nbsp;</p>
<p>Not too bad for a couple of day&#8217;s work. Hopefully with some free time I can put in all the features I want in a fortnight or so and eventually share it for like minded individuals to find the bugs.</p>
<p>Note that I&#8217;ve not paid too much attention to the look and feel. That, naturally&nbsp;will be a distant last.</p>
<p>In the process of writing this application I have had to consult MSDN and Google heavily to overcome some of the problems that i have run into. I have also learnt quite a bit, which is the purpose of this series.</p>
<p>I hope to share with you, dear reader, some of the challenges I have run into and how I have solved them. A great man said we see far because we stand on the shoulders of great men. Hopefully after I have shared some of my problems and thoughts, we will all be the wiser for it.</p>
<p>I hope to also capture my logic in moving from an idea to a design to a working application. Ideas, as ever, are most welcome.</p>
<p><strong>Stay tuned for Episode Two: Understanding The Problem(s)</strong></p>
<p>NB: Those about to start being outraged at my re-inventing the wheel, hold your horses until we get to Episode Two!</p>
<p> <a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fthinkersroom.com%2fbytes%2f2007%2f10%2f31%2fbuilding-a-feed-reader-episode-one%2f"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fthinkersroom.com%2fbytes%2f2007%2f10%2f31%2fbuilding-a-feed-reader-episode-one%2f" border="0" alt="kick it on DotNetKicks.com"></a>
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/10/31/building-a-feed-reader-episode-one/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Profiling .NET Applications I</title>
		<link>http://thinkersroom.com/bytes/2007/10/01/profiling-net-applications-i/</link>
		<comments>http://thinkersroom.com/bytes/2007/10/01/profiling-net-applications-i/#comments</comments>
		<pubDate>Mon, 01 Oct 2007 15:50:21 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>C#</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/10/01/profiling-net-applications-i/</guid>
		<description><![CDATA[If you are a serious developer, you are certain to have either come across or used tools to profile your application. This will let you know a couple of things about your code:

How fast it (the program) executes
How fast each method&#160;executes
Bottlenecks within the code
Number of times loops execute
Memory usage
Number of objects created

These are pretty useful [...]]]></description>
			<content:encoded><![CDATA[<p>If you are a serious developer, you are certain to have either come across or used tools to profile your application. This will let you know a couple of things about your code:</p>
<ol>
<li>How fast it (the program) executes</li>
<li>How fast each <strong>method</strong>&nbsp;executes</li>
<li>Bottlenecks within the code</li>
<li>Number of times loops execute</li>
<li>Memory usage</li>
<li>Number of objects created</li>
</ol>
<p>These are pretty useful metrics that can help you identify notoriously difficult to identify bugs, such as memory leaks. They also show you where you can concentrate on optimizing your code.</p>
<p>For this example I will use a very trivial console application that does nothing more than concatenate a large number of strings. This is in a static function imaginatively called ConcatenateWithPlus()</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">class</span> Program</pre>
<pre><span class="lnum">   2:</span>     {</pre>
<pre class="alt"><span class="lnum">   3:</span>         <span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)</pre>
<pre><span class="lnum">   4:</span>         {</pre>
<pre class="alt"><span class="lnum">   5:</span>             ConcatWithPlus();         </pre>
<pre><span class="lnum">   6:</span>         }</pre>
<pre class="alt"><span class="lnum">   7:</span>         <span class="kwrd">static</span> <span class="kwrd">void</span> ConcatWithPlus()</pre>
<pre><span class="lnum">   8:</span>         {</pre>
<pre class="alt"><span class="lnum">   9:</span>             Random r = <span class="kwrd">new</span> Random(0);</pre>
<pre><span class="lnum">  10:</span>             <span class="kwrd">string</span> s = <span class="str">&#8220;&#8221;</span>;</pre>
<pre class="alt"><span class="lnum">  11:</span>             <span class="kwrd">for</span>(<span class="kwrd">int</span> i =0;i &lt;5000;i++)</pre>
<pre><span class="lnum">  12:</span>             {</pre>
<pre class="alt"><span class="lnum">  13:</span>                 s += r.NextDouble().ToString();</pre>
<pre><span class="lnum">  14:</span>             }</pre>
<pre class="alt"><span class="lnum">  15:</span>         }        </pre>
<pre><span class="lnum">  16:</span>     }</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>A couple of interesting things to note:</p>
<ol>
<li>It is entirely possible that if we used the same string repeatedly to concatenate, the compiler or the runtime might make some optimizations to improve the performance. To avoid this I use the random class to generate 5000 (pseudo) random strings</li>
<li>Yes yes, pseudo random. This is because I want to generate the exact same sequence of strings. You&#8217;ll see why shortly</li>
</ol>
<p>So, the next thing to do is run the application through a profiler. The better known ones are <a href="http://www.red-gate.com/">Red Gate Software&#8217;s</a> <a href="http://www.red-gate.com/products/ANTS_Profiler/index.htm">ANTS Profiler</a> and <a href="http://www.jetbrains.com">JetBrains&#8217;</a> <a href="http://www.jetbrains.com/profiler/">dotTrace</a>. Today I will use ANTS. (Both have evaluation versions you can download to check out)</p>
<p>First, open ANTS</p>
<p><img alt="ants1" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants1.gif"> </p>
<p>This is the screen you should get</p>
<p><img alt="ants 2" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%202.gif"> </p>
<p>We want the detailed mode. Click next</p>
<p><img alt="ants 3" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%203.gif"> </p>
<p>As you can see, quite a number of applications can be profiled. A console application is a .NET desktop application so we select that an move on to the next screen.</p>
<p><img alt="ants 4" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%204.gif"> </p>
<p>Here select the executable that you want to run. In our case, the console app.</p>
<p><img alt="ants 5" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%205.gif"> </p>
<p>The final screen gives you control over what to profile. We can if we want also profile the .NET classes, or choose exactly what we want to profile. For simplicity, let&#8217;s take the first choice. Then click Finish and we&#8217;re off.</p>
<p><img alt="ants 6" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%206.gif"> </p>
<p>Yes I do!</p>
<p><img alt="ants 8" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%208.gif"> </p>
<p>You should get something like you see above </p>
<p>The points of interest are the following:</p>
<ol>
<li>The <strong>summary</strong> pane gives you an overview of the profile that has just been run and two reports:</li>
<ul>
<li>Slowest Lines Of Code</li>
<li>Slowest Methods</li>
</ul>
<li>The <strong>all methods</strong> pane gives you a grid with all the profiled methods and some metrics, such as time (for the method itself) and time with children (for the method and any other methods it calls)</li>
<li>The <strong>source code pane</strong> gives you the actual source code and time taken for each line of code. This is very valuable information because you can identify any slow algorithms and method calls.</li>
</ol>
<p><img height="827" alt="ants 9" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%209.gif" width="489"> </p>
<p>The all methods pane tell us that the ConcatWithPlus() call is the slowest, at 0.482 seconds. Can we improve this? Methinks so.</p>
<p>String concatenation is a very slow process. Due to the fact that they are immutable (cannot be changed once created), any method that purports to manipulate a string actucally creates a new string with the manipulations. So stuff like ToUpper(), ToLower(), etc actually creates a new string and returns the new instance.</p>
<p>Naturally, concatenation also has the same side effect. So in effect our code creates 5,000 string objects.</p>
<p>Hmm.</p>
<p>Can we avoid 5,000 string objects being created? Turns out that we can.</p>
<p>Enter the <a href="http://msdn2.microsoft.com/en-us/library/system.text.stringbuilder(VS.71).aspx">StringBuilder</a>.</p>
<p>This is an object designed for precisely this sort of thing. So let&#8217;s create a second method that uses a StringBuilder.</p>
<p>Modify your code as follows:</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">class</span> Program</pre>
<pre><span class="lnum">   2:</span>     {</pre>
<pre class="alt"><span class="lnum">   3:</span>         <span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)</pre>
<pre><span class="lnum">   4:</span>         {</pre>
<pre class="alt"><span class="lnum">   5:</span>             ConcatWithPlus();</pre>
<pre><span class="lnum">   6:</span>             ConcatWithStringBuilder();</pre>
<pre class="alt"><span class="lnum">   7:</span>         }</pre>
<pre><span class="lnum">   8:</span>         <span class="kwrd">static</span> <span class="kwrd">void</span> ConcatWithPlus()</pre>
<pre class="alt"><span class="lnum">   9:</span>         {</pre>
<pre><span class="lnum">  10:</span>             Random r = <span class="kwrd">new</span> Random(0);</pre>
<pre class="alt"><span class="lnum">  11:</span>             <span class="kwrd">string</span> s = <span class="str">&#8220;&#8221;</span>;</pre>
<pre><span class="lnum">  12:</span>             <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; 5000; i++)</pre>
<pre class="alt"><span class="lnum">  13:</span>             {</pre>
<pre><span class="lnum">  14:</span>                 s += r.NextDouble().ToString();</pre>
<pre class="alt"><span class="lnum">  15:</span>             }</pre>
<pre><span class="lnum">  16:</span>         }</pre>
<pre class="alt"><span class="lnum">  17:</span>         <span class="kwrd">static</span> <span class="kwrd">void</span> ConcatWithStringBuilder()</pre>
<pre><span class="lnum">  18:</span>         {</pre>
<pre class="alt"><span class="lnum">  19:</span>             Random r = <span class="kwrd">new</span> Random(0);</pre>
<pre><span class="lnum">  20:</span>             System.Text.StringBuilder sb = <span class="kwrd">new</span> System.Text.StringBuilder();</pre>
<pre class="alt"><span class="lnum">  21:</span>             <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; 5000; i++)</pre>
<pre><span class="lnum">  22:</span>             {</pre>
<pre class="alt"><span class="lnum">  23:</span>                 sb.Append(r.NextDouble().ToString());</pre>
<pre><span class="lnum">  24:</span>             }</pre>
<pre class="alt"><span class="lnum">  25:</span>         }</pre>
<pre><span class="lnum">  26:</span>     }</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>Now, we run the profiler again, by clicking the green Go button or Control + G</p>
<p>Then click the All Methods pane. The results should be interesting</p>
<p><img alt="ants 11" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%2011.gif"> </p>
<p>The method with the StringBuilder is <strong>several orders of magnitude faster</strong> than the concatenation!</p>
<p>The source code view reveals the same information slightly differently</p>
<p><img alt="ants 12" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/10/ants%2012.gif"> </p>
<p>You can see the line with</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> s += r.NextDouble();</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>Has a little red bar after the time (0.427). This is a contribution of that line of code to the total time taken. Notice the corresponding line for the StringBuilder</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> sb.Append(r.NextDouble().ToString());</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>Does not have the bar. This is because graphing 0.0099 next to 0.430 is a bit of a stretch.</p>
<p>Thus we see the profiler has helped us identify a bottleneck and we have investigated how to correct it. Version 2 of our do nothing application will be MUCH faster.</p>
<h4>AOB</h4>
<p>Now, back to that Random business.</p>
<p>The System.Random class does not actually generate truly random numbers. In fact it is fairly predictable because given the same seed it generates the same sequence of numbers. I used this to generate a large set of randomish yet predictable strings for the test.</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://thinkersroom.com/bytes/2007/10/01/profiling-net-applications-i/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://thinkersroom.com/bytes/2007/10/01/profiling-net-applications-i/" border="0" alt="kick it on DotNetKicks.com"></a>
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/10/01/profiling-net-applications-i/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Excel&#8217;s Interesting Bug: Thoughts</title>
		<link>http://thinkersroom.com/bytes/2007/09/25/interesting-bug/</link>
		<comments>http://thinkersroom.com/bytes/2007/09/25/interesting-bug/#comments</comments>
		<pubDate>Tue, 25 Sep 2007 13:01:55 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Software</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/09/25/interesting-bug/</guid>
		<description><![CDATA[Microsoft Excel 2007 has an interesting, albeit embarrassing bug.
Type the following into a shiny new spreadsheet
 
Press Enter and you should see the following
 
Then, type the following
 
You&#8217;d think you&#8217;d get the same result. This is where you would be wrong
 
Let&#8217;s try with other factors
 
The result?
 
Ok, maybe there&#8217;s something special about [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft Excel 2007 has an interesting, albeit embarrassing bug.</p>
<p>Type the following into a shiny new spreadsheet</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="271" alt="first" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/first.png" width="514" border="0"> </p>
<p>Press Enter and you should see the following</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="second" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/second.png" border="0"> </p>
<p>Then, type the following</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="third" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/third.png" border="0"> </p>
<p>You&#8217;d think you&#8217;d get the same result. This is where you would be wrong</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="fourth" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/fourth.png" border="0"> </p>
<p>Let&#8217;s try with other factors</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="fifth" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/fifth.png" border="0"> </p>
<p>The result?</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="sixth" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/sixth.png" border="0"> </p>
<p>Ok, maybe there&#8217;s something special about 77.1, 850 and multiplication.</p>
<p>From what I remember from school, A * B = A / (1/B). Let&#8217;s see if Excel 2007 agrees</p>
<p>Type the following</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="seventh" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/seventh.png" border="0"> </p>
<p>Then type the following formula and fill down</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="292" alt="eighth" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/eighth.png" width="513" border="0">&nbsp;</p>
<p>What do you reckon the results will be? Without further ado:</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" alt="ninth" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/ninth.png" border="0"> </p>
<p>The point of this post is not to gleefully point out the bug. I have my fair share of the same!&nbsp;<strong>And so do you</strong>! It is to merely speculate</p>
<ol>
<li>What conditions in the algorithm the Excel guys used could lead to such a situation? Does it have anything to do with the number 65535, that just happens to be 2^16?</li>
<li>Since the bug manifests itself in the division, it conjures up some food for thought. In the division algorithm does it actually divide or does it reduce the expression directly to multiplication?</li>
<li>Where else will this beast rear its head? For instance, some formulas make use of multiplication</li>
<li>Are there any other magic numbers that cause this behaviour?</li>
<li>How do you test for this, short of writing tests for all permutations of numbers being added/divided/multiplied/subtracted?</li>
</ol>
<p>&nbsp;</p>
<p> <a href="http://www.dotnetkicks.com/kick/?url=http://thinkersroom.com/bytes/2007/09/25/interesting-bug/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://thinkersroom.com/bytes/2007/09/25/interesting-bug/" border="0" alt="kick it on DotNetKicks.com"></a>
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/09/25/interesting-bug/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rolling Back Truncates</title>
		<link>http://thinkersroom.com/bytes/2007/09/21/rolling-back-truncates/</link>
		<comments>http://thinkersroom.com/bytes/2007/09/21/rolling-back-truncates/#comments</comments>
		<pubDate>Fri, 21 Sep 2007 07:10:35 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>SQL Server</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/09/21/rolling-back-truncates/</guid>
		<description><![CDATA[Being the kind of advanced chap that can walk and chew gum at the same time, I generally listen to music as I work. And a few minutes ago I was listening to Kanye West&#8217;s I Wonder, from his Graduation Album. Brilliant does not begin to describe it. You need to listen to that song.
&#160;
But [...]]]></description>
			<content:encoded><![CDATA[<p>Being the kind of advanced chap that can walk and chew gum at the same time, I generally listen to music as I work. And a few minutes ago I was listening to Kanye West&#8217;s I Wonder, from his Graduation Album. Brilliant does not begin to describe it. You need to listen to that song.</p>
<p>&nbsp;</p>
<p>But I digress.</p>
<p>&nbsp;</p>
<p>Point is, as I typed away at my SQL Server 2005 Management studio and flipped between a random PDF that said that it was impossible to roll back truncates, I Wondered &#8230;</p>
<p>&nbsp;</p>
<p>And if at first you don&#8217;t succeed, try try it yourself.</p>
<p>&nbsp;</p>
<p>First, a dummy database to hold all our experiments</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">create</span> <span class="kwrd">database</span> Springfield</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>Next create a table to store the test data</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">create</span> <span class="kwrd">table</span> Residents(</pre>
<pre><span class="lnum">   2:</span>     ID <span class="kwrd">int</span> <span class="kwrd">identity</span>,</pre>
<pre class="alt"><span class="lnum">   3:</span>     FirstName <span class="kwrd">varchar</span>(50),</pre>
<pre><span class="lnum">   4:</span>     Age <span class="kwrd">int</span></pre>
<pre class="alt"><span class="lnum">   5:</span> )</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>Next create some sample data. For the slower ones among us I&#8217;m sure a pattern is emerging!</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Homer&#8217;</span>, 40)</pre>
<pre><span class="lnum">   2:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Marge&#8217;</span>, 35)</pre>
<pre class="alt"><span class="lnum">   3:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Bart&#8217;</span>, 11)</pre>
<pre><span class="lnum">   4:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Lisa&#8217;</span>, <img src='http://thinkersroom.com/bytes/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> </pre>
<pre class="alt"><span class="lnum">   5:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Maggie&#8217;</span>, 3)</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>Now select and see our nice clean data</p>
<p><img alt="select-1" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/select-1.gif"> </p>
<p>Awesome.</p>
<p>Now from past experience, truncate and delete affect identity columns differently. To make our experiment a bit less misleading, what we&#8217;ll do is to find a way to make the IDs NOT begin from 1. A simple delete will suffice, then we recreate our residents again</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">delete</span> <span class="kwrd">from</span> Residents</pre>
<pre><span class="lnum">   2:</span> <span class="kwrd">go</span></pre>
<pre class="alt"><span class="lnum">   3:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Homer&#8217;</span>, 40)</pre>
<pre><span class="lnum">   4:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Marge&#8217;</span>, 35)</pre>
<pre class="alt"><span class="lnum">   5:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Bart&#8217;</span>, 11)</pre>
<pre><span class="lnum">   6:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Lisa&#8217;</span>, 8 )</pre>
<pre class="alt"><span class="lnum">   7:</span> insert <span class="kwrd">into</span> Residents(FirstName,Age) <span class="kwrd">values</span> (<span class="str">&#8216;Maggie&#8217;</span>, 3)</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>Our data now looks like this</p>
<p>&nbsp;</p>
<p><img alt="select-2" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/select-2.gif"> </p>
<p>Right. Now let&#8217;s get cracking.</p>
<p>&nbsp;</p>
<p>Even the most shiny faced new programmer is aware of the mysterious thing called the transaction that allows you to <strike>recover data from the live table you delete my mistake</strike>&nbsp;preserve atomicity of transactions. So what we&#8217;ll do is create&nbsp; a transaction and within it delete all the data and roll it back</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">begin</span> <span class="kwrd">tran</span></pre>
<pre><span class="lnum">   2:</span> <span class="kwrd">delete</span> <span class="kwrd">from</span> Residents;</pre>
<pre class="alt"><span class="lnum">   3:</span> <span class="kwrd">select</span> * <span class="kwrd">from</span> Residents;</pre>
<pre><span class="lnum">   4:</span> <span class="kwrd">rollback</span>;</pre>
<pre class="alt"><span class="lnum">   5:</span> <span class="kwrd">select</span> * <span class="kwrd">from</span> Residents;</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>Our data will now look like this. Which should be the same as above</p>
<p>&nbsp;</p>
<p><img alt="select-2" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/select-21.gif"> </p>
<p>Right. Now let&#8217;s try the same query with truncate instead of delete</p>
<p>&nbsp;</p>
<div>
<div class="csharpcode">
<pre class="alt"><span class="lnum">   1:</span> <span class="kwrd">begin</span> <span class="kwrd">tran</span></pre>
<pre><span class="lnum">   2:</span> <span class="kwrd">truncate</span> <span class="kwrd">table</span> Residents;</pre>
<pre class="alt"><span class="lnum">   3:</span> <span class="kwrd">select</span> * <span class="kwrd">from</span> Residents;</pre>
<pre><span class="lnum">   4:</span> <span class="kwrd">rollback</span>;</pre>
<pre class="alt"><span class="lnum">   5:</span> <span class="kwrd">select</span> * <span class="kwrd">from</span> Residents;</pre>
</div>
<p><style type="text/css">.csharpcode-wrapper, .csharpcode-wrapper pre {<br />
  background-color: #f4f4f4;<br />
  border: solid 1px gray;<br />
  cursor: text;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  margin: 20px 0px 10px 0px;<br />
  max-height: 200px;<br />
  overflow: auto;<br />
  padding: 4px 4px 4px 4px;<br />
  width: 97.5%;<br />
}<br />
.csharpcode-wrapper pre {<br />
  border-style: none;<br />
  margin: 0px 0px 0px 0px;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
}<br />
.csharpcode, .csharpcode pre, .csharpcode .alt {<br />
  background-color: #f4f4f4;<br />
  border-style: none;<br />
  color: black;<br />
  font-family: consolas, &#8216;Courier New&#8217;, courier, monospace;<br />
  font-size: 8pt;<br />
  line-height: 12pt;<br />
  overflow: visible;<br />
  padding: 0px 0px 0px 0px;<br />
  width: 100%;<br />
}<br />
.csharpcode pre {<br />
  margin: 0em;<br />
}<br />
.csharpcode .alt {<br />
  background-color: white;<br />
}<br />
.csharpcode .asp {<br />
  background-color: #ffff00;<br />
}<br />
.csharpcode .attr {<br />
  color: #ff0000;<br />
}<br />
.csharpcode .html {<br />
  color: #800000;<br />
}<br />
.csharpcode .kwrd {<br />
  color: #0000ff;<br />
}<br />
.csharpcode .lnum {<br />
  color: #606060;<br />
}<br />
.csharpcode .op {<br />
  color: #0000c0;<br />
}<br />
.csharpcode .preproc {<br />
  color: #cc6633;<br />
}<br />
.csharpcode .rem {<br />
  color: #008000;<br />
}<br />
.csharpcode .str {<br />
  color: #006080;<br />
}<br />
</style>
</div>
<p>&nbsp;</p>
<p>The results pane should be as follows:</p>
<p>&nbsp;</p>
<p><img alt="select-3" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/select-3.gif"> </p>
<p>&nbsp;</p>
<h4>Observations</h4>
<p>My dear Watson, I do believe the following</p>
<ol>
<li>The truncate has been rolled back, just like the delete</li>
<li>The truncate appears to have preserved the identity values, and not started again from 1&nbsp;(I&#8217;d be amazed if it did otherwise, this being a rollback and all, but one should not assume!). </li>
</ol>
<h4>Moral</h4>
<p>Truncates can be rolled back, at least for SQL 2005. I&#8217;ll try and find a SQL 2000 box somewhere and see if it also holds true there.</p>
<h4>Caveat</h4>
<p>This is not always true. Truncates fail spectacularly if the table being truncated, hereby called the truncatee, is participating in a foreign key relationship. To be exact, if&nbsp;is being referenced.</p>
<p>&nbsp;</p>
<p><a href="http://www.dotnetkicks.com/kick/?url=http://thinkersroom.com/bytes/2007/09/21/rolling-back-truncates/"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://thinkersroom.com/bytes/2007/09/21/rolling-back-truncates/" border="0" alt="kick it on DotNetKicks.com"></a>
</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/09/21/rolling-back-truncates/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Odds &#38; Ends</title>
		<link>http://thinkersroom.com/bytes/2007/09/18/odds-ends/</link>
		<comments>http://thinkersroom.com/bytes/2007/09/18/odds-ends/#comments</comments>
		<pubDate>Tue, 18 Sep 2007 08:23:43 +0000</pubDate>
		<dc:creator>Rad!</dc:creator>
		
		<category>Software</category>

		<guid isPermaLink="false">http://thinkersroom.com/bytes/2007/09/18/odds-ends/</guid>
		<description><![CDATA[No, I have not died. I have been very much alive but have had pressing commitments on other levels that have kept me from contributing actively to Bits &#38; Bytes, something I shall correct forthwith! Regular programming will resume soon.
As a happy iPod classic owner (I&#8217;m tempted by the iPod touch but 16 GB of [...]]]></description>
			<content:encoded><![CDATA[<p>No, I have not died. I have been very much alive but have had pressing commitments on other levels that have kept me from contributing actively to Bits &amp; Bytes, something I shall correct forthwith! Regular programming will resume soon.</p>
<p>As a happy iPod classic owner (I&#8217;m tempted by the iPod touch but 16 GB of storage does not cut it for me), getting stuff, especially DVDs onto the iPod is a problem and then some. I&#8217;ve spent months looking for the best rippers, and have tried&nbsp; out over 15. Yes. 15. Finally yesterday I chanced on GOLD. Ladies and gentlemen if you want to get DVDs onto iPods, or indeed any other device, look no further than <a href="http://www.slysoft.com/en/clonedvd-mobile.html">SlySoft Clone DVD Mobile</a>. Awesome does not begin to describe it!</p>
<p>The first step is selecting the device you want the video to go to</p>
<p><img alt="Clone1" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/Clone1.gif"> </p>
<p>Next browse to the Video_TS Folder and watch your videos loaded</p>
<p><img alt="Clone2" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/Clone2.gif"> </p>
<p>You can even preview the video if so inclined. Finally you get a chance to tweak various aspects of the video &#8212; resolution, file size, number of passes, and so on, one&nbsp;of the most powerful features. Not many rippers offer this.</p>
<p><img alt="Clone3" src="http://thinkersroom.com/bytes/wp-content/uploads/2007/09/Clone3.gif"> </p>
<p>Finally you hit go and away you go! And there is where more features becomes apparent. It can correct those annoying DVDs that have the audio out of sync with the video. Also, I had a DVD that was partially scratched near the end of the movie. Unlike most rippers that threw up their hands and gave me a 600MB useless file, Clone DVD Mobile rendered the file until the point of damage, so I can, if I chose to, watch the first 130 minutes of Coach Carter.</p>
<p>Brilliant.</p>
<p>And no, I have no affiliation with <a href="http://www.slysoft.com">SlySoft</a>. I just love their product. You can get a 21 day demo that FULLY WORKS. None of that 10 minute limit nonsense.</p>
<p>Seriously, buy it if you can.</p>
<img src="http://thinkersroom.com/bytes/f30b6ac6/26673f3c/CCBot/1.0 (+http://www.commoncrawl.org/bot.html).gif" />]]></content:encoded>
			<wfw:commentRss>http://thinkersroom.com/bytes/2007/09/18/odds-ends/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
