
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
  <channel>
    <title>Stu Smith: Making It Up As I Go Along</title>
    <link>http://www.feedghost.com/Blogs/BlogArchive.aspx?blogId=stusmith</link>
    <description >
			My life working for BinaryComponents, coding, design, and other stuff.
    </description>
    <dc:language>en-US</dc:language>
    <generator>FeedGhost</generator>
    
    <item>
      <title>Eliminate Those Loops! - or - 'foreach' Considered Harmful</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17841</link>
      <pubDate>Wed, 28 May 2008 16:12:56 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17841</guid>
      <description>
        	&lt;p&gt;Lee and I are working on a project at the moment, and we got into a mini-argument about how best to write a tiny piece of code. Essentially, we're working with a thrid-party API that returns some data as key/value pairs in a hastable: the keys are always strings, but the values can be either strings, or further hashtables. (So essentially we have a tree structure). For the purposes of this discussion, we need to render that tree as XML.&lt;/p&gt;  &lt;p&gt;Here's the &quot;traditional&quot; method of accomplishing this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;pre&gt;public static XDocument ConvertDictionaryToXml( IDictionary dictionary )
{
 XElement root = new XElement( &quot;root&quot; );

 ConvertDictionaryToXml( root, dictionary );

 return new XDocument( root );
}

public static void ConvertDictionaryToXml( XElement parent, IDictionary dictionary )
{
 foreach( DictionaryEntry kv in dictionary )
 {
  XElement newElement = new XElement( kv.Key.ToString() );

  if( kv.Value is IDictionary )
  {
   ConvertDictionaryToXml( newElement, (IDictionary)kv.Value );
  }
  else
  {
   newElement.Value = kv.Value.ToString();
  }
  parent.Add( newElement );
 }
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now I disagree with this - it's my belief that loops should go the way of the &quot;goto&quot; statement and be consigned to history. Here's my version:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;pre&gt;public static XDocument ConvertDictionaryToXml( IDictionary dictionary )
{
 var root = new XElement( &quot;root&quot;, DictionaryToXElement( dictionary ) );

 return new XDocument( root );
}

private static XElement[] DictionaryToXElement( IDictionary sourceDictionary )
{
 var xelements = from DictionaryEntry p in sourceDictionary
   let dp = p.Value as IDictionary
   select (dp == null)
    ? new XElement( p.Key.ToString(), p.Value.ToString() )
    : new XElement( p.Key.ToString(), DictionaryToXElement( dp ) );

 return xelements.ToArray();
}&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Short and sweet. No (visible) changing state to understand, just a recursive sequence transform. I see parallels here in the new WPF model of animation: in the older WinForms, to animate something, you'd set up a timer and repeatedly change it. In the newer WPF, you simply set up the intent of the animation, and the system handles the messy updating stuff.&lt;/p&gt;

&lt;p&gt;I see it as a natural progression in the power of languages:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;C# 1.0 - zero-dimensional. Language support limited to operations on single data items.&lt;/li&gt;

  &lt;li&gt;C# 3.0 - one-dimensionalLanguage supports operations on sequences of data items.&lt;/li&gt;

  &lt;li&gt;C# N.0 - two-dimensional. Language supports operations on trees/graphs of data items.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Incidentally, I'm well aware of the similarities to languages like LISP or Haskell - and if you think LISP is old-fashioned, you should probably have a read of &lt;a href=&quot;http://www.amazon.co.uk/Structure-Interpretation-Computer-Electrical-Engineering/dp/0262510871/&quot; target=&quot;_blank&quot;&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;If you're worried about performance, well, I guess there could be a hit with my version, you'd have to profile it, but on the other hand the LINQ version would parallelize nicely using &lt;a href=&quot;http://msdn.microsoft.com/en-us/magazine/cc163329.aspx&quot; target=&quot;_blank&quot;&gt;PLINQ&lt;/a&gt;, something that can't be said for arbitrary for-loops. (Of course, if we were worried about performance, we wouldn't be using XML).&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Microsoft Word Mail-Merge: Grrr</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17838</link>
      <pubDate>Tue, 15 Apr 2008 11:58:36 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17838</guid>
      <description>
        	&lt;p&gt;I'm sorry, I have to rant today. It's been building up inside me for a while, and now I can't contain it. Here's my tale of woe.&lt;/p&gt;  &lt;p&gt;We're looking to expand the contracting side of the business at the moment, and one of the things I'm doing is sending small (50-100 recipient) mailshots out about once a month to potential customers or other companies we can work with. (Aside: fifty quid spent on stamps, envelopes, and printed flyers has a much, much greater return than the equivalent amount spent on Google ads).&lt;/p&gt;  &lt;p&gt;So I have my list of addresses in an Excel spreadsheet, I have my labels ready, my printer is on, and I'm full of coffee. It should be a ten-minute job but it seems that the mail-merge feature in Word is a second-class citizen, and doesn't have that level of polish that the rest of the application does.&lt;/p&gt;  &lt;p&gt;(And I really like the rest of the application - Microsoft have done great things with the latest version; they've taken a much-need risk with the new UI, have come up with a great new alternative to a complex menu system, and have really brought things up-to-date with the new style set and charting system).&lt;/p&gt;  &lt;p&gt;Just through trying to print labels, I've found the following bugs. Not show-stoppers, obviously, but annoying as hell. I'll categorize them by operation.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Mailings -&amp;gt; Start Mail Merge -&amp;gt; Labels...&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Defaults to manual tray. Every time. Even though that's the worst option on my printer. And if I forget to choose Tray 1, I get to the end of the mail-merge, won't be able to print, and will have to start all over again. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Select Recipients -&amp;gt; Use Existing List...&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;File browser always resets to &quot;All Data Sources&quot;. My spreadsheet isn't there, so I always have to browse for it. &lt;/li&gt;    &lt;li&gt;&quot;First row of data contains column headers&quot;. You better hope your spreadsheet fits this pattern, because if it doesn't, even if you uncheck this option, you won't be able to print the first address. &lt;/li&gt;    &lt;li&gt;By default, Excel creates three sheets. I would guess that 99% of spreadsheets only use the first one. Surely Word could filter out the empty sheets in the list? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Update Labels&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;OK, I'm not a mail-merge wizz, so maybe there's some special case I'm not aware of here. But basically, any time you make a change, you have to click &quot;Update Labels&quot;. Couldn't this be automatic? Or perhaps, a checkbox for automatic/manual? &lt;/li&gt;    &lt;li&gt;Line spacing. The labels default to paragraph-spacing between each address line, which means that the address won't fit on the labels. The solution is to highlight the address block, go to the home tab, then select &quot;No Spacing&quot;, go back to the Mailings tab, and click &quot;Update Labels&quot;. Would &quot;no spacing&quot; from the get-go be a better default? I think so. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Back to Excel&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;So I'm trying to figure stuff out. I want to open the source spreadsheet to compare. Excel tells me that the file format or file extension is not valid. So (a) it gives me an incorrect error message (actually the file is in use), and (b) Word surely doesn't need to keep the file open? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Preview Results&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When previewing results, the back/forward buttons move in steps of one record. So to preview the next page, I have to know my 14-times table. Perhaps we could also have page back/page next buttons? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;So What's the Solution?&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;Start testing the mail-merge feature. Not from specs, but from a task-based standpoint: actually buy some labels, use a cheap laser or inkjet printer, and see how long it takes.&lt;/li&gt;    &lt;li&gt;Fix up the immediate problems. Have Word remember certain critical settings (such as data source locations and default printer trays). Fix Excel's confusing error messages.&lt;/li&gt;    &lt;li&gt;Separate out orthogonal concepts. For example, the choice of tray to use in the printer could logically be modified in complete isolation to every other aspect of the mail-merge process. Unfortunately, with the current design, if you need to change it, you have to start the entire process from scratch. &lt;/li&gt;    &lt;li&gt;Identify key tasks the user performs, and build the user interface around that. For example: you can choose the basic layout of the labels by manufacturer, but I often find that I've got my margins slightly wrong. Instead of having to go back to the beginning to reset the label layout, why not have a &quot;nudge&quot; feature to allow slight adjustments to the margins? If I realise I've picked the wrong source spreadsheet, let me just change that: I don't want to to have to re-format all my address lines first. (This &quot;task-based&quot; approach has worked very nicely with new features such as style-sets, and cover pages). &lt;/li&gt; &lt;/ol&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Annoyances</category>
				
    </item>
    
    <item>
      <title>My Other Blog</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17837</link>
      <pubDate>Fri, 28 Mar 2008 16:16:32 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17837</guid>
      <description>
        	&lt;p&gt;I've been a bit slack with my blog posts lately - or rather, they've mostly been about things other than FeedGhost, so they've gone on my other blog.&lt;/p&gt;  &lt;p&gt;If you didn't know about my other blog, it's called &lt;a href=&quot;http://www.justeffort.com/&quot; target=&quot;_blank&quot;&gt;Just Effort&lt;/a&gt; (tagline: design skills are something you learn, not something you&amp;#8217;re born with). It's all about graphic design, but from my perspective, i.e. that of a programmer. &lt;strong&gt;It's my belief that the stereotype of &quot;programmer art&quot; is down to lack of effort and practice, not some lack of innate skill.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;So what might you find there? Here's a few past articles:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Getting Past Blank-Canvas-Block&lt;/h3&gt;  &lt;p&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;94&quot; alt=&quot;Existing&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Existing.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;120&quot; alt=&quot;Content&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Content.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;120&quot; alt=&quot;Final&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Final.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;  &lt;p&gt;How to get past the blank canvas and actually produce something.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Vista-Style Transparency&lt;/h3&gt;  &lt;p&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;134&quot; alt=&quot;Frosted3&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Frosted3.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;95&quot; alt=&quot;Frosted4&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Frosted4.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;100&quot; alt=&quot;Frosted5&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Frosted5.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;  &lt;p&gt;Using Photoshop to produce a frosted glass effect.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;Designing and Printing Business Stationery&lt;/h3&gt;  &lt;p&gt;&amp;#160; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;117&quot; alt=&quot;sketch&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/sketch.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;161&quot; alt=&quot;brochure-3a&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/brochure3a.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;160&quot; alt=&quot;Letterhead&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/Letterhead.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;Ideas and how-to guides for producing promotional business materials.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;3-D Reflective Screenshots&lt;/h3&gt;  &lt;p&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;126&quot; alt=&quot;addlayermask&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/addlayermask.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;178&quot; alt=&quot;draggradient&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/draggradient.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;122&quot; alt=&quot;3d6&quot; src=&quot;http://www.feedghost.com/BlogImages/MyOtherBlog_D454/3d6.png&quot; width=&quot;120&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;  &lt;p&gt;Making attractive reflective screenshots to show off your software.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;You can find the blog here:&lt;/p&gt;  &lt;p&gt;&lt;a title=&quot;http://www.justeffort.com/&quot; href=&quot;http://www.justeffort.com/&quot;&gt;http://www.justeffort.com/&lt;/a&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Other</category>
				
    </item>
    
    <item>
      <title>I've Got the 64-bit Blues</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17829</link>
      <pubDate>Wed, 20 Feb 2008 16:32:19 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17829</guid>
      <description>
        	&lt;p&gt;Pretty much all my development work at BinaryComponents has been done on a nice little Dell that we bought about 18 months ago, originally supplied with XP Pro. Unfortunately, in common with most desktop machines, it's been getting slower and slower as the cruft accumulated. Finally it all got too much for me, and I decided to wipe the whole lot and install Vista instead - and since I can see 2Gb RAM isn't going to be enough for much longer, I decided to go for a 64-bit version.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;132&quot; alt=&quot;Vista Business 64&quot; src=&quot;http://www.feedghost.com/BlogImages/IveGotthe64bitBlues_C248/image.png&quot; width=&quot;324&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As you can see, it's all installed nicely, with service pack 1 on too, and in general it's a pleasure to use. There is one exception unfortunately... as some of our users have pointed out on the forums, FeedGhost has a few issues when running on 64-bit Vista. This week, I've been tracking them down. Here's one of them:&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;248&quot; alt=&quot;FeedGhost 64-bit issues&quot; src=&quot;http://www.feedghost.com/BlogImages/IveGotthe64bitBlues_C248/BadLayout.png&quot; width=&quot;257&quot; border=&quot;0&quot; /&gt; &lt;/p&gt;  &lt;p&gt;Yuck. It's not even as if FeedGhost is coded in some legacy language; it's a pretty standard .NET / Windows Forms application really.&lt;/p&gt;  &lt;p&gt;A couple of days' hair-tearing, debugging, tracing, and stepping through the framework source code led me to this in Control.SetBoundsCore (Microsoft code, Microsoft comments):&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;     &lt;p style=&quot;margin: 0px&quot;&gt;SafeNativeMethods.SetWindowPos(&lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;HandleRef&lt;/span&gt;(window, Handle), NativeMethods.NullHandleRef, x, y, width, height, flags);&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: green&quot;&gt;// NOTE: SetWindowPos causes a WM_WINDOWPOSCHANGED which is processed&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: green&quot;&gt;// synchonously so we effectively end up in UpdateBounds immediately following &lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: green&quot;&gt;// SetWindowPos. &lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: green&quot;&gt;//UpdateBounds(x, y, width, height); &lt;/span&gt;&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;I now had enough information to cross-reference with an &lt;a href=&quot;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2213006&amp;amp;SiteID=1&quot; target=&quot;_blank&quot;&gt;MSDN forum post&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&quot;A little investigation showed that Windows stops sending WM_SIZE when it reaches some certain nesting level. In other words, it won't send WM_SIZE to your child windows if you try to resize them when you process WM_SIZE in the parent ones. Depending on the USER stuff/updates/serivice packs the maximum nesting level at which it stops propagating WM_SIZE may vary from 15 to 31 and even much higher (effectively unreachable) under latest XP 32bit/sp2.&lt;/p&gt;    &lt;p&gt;But it still too little under XP x64 and still some similar ugly things happen to other messages under some builds of Vista. &lt;/p&gt;    &lt;p&gt;So it is certainly a Windows bug.&quot;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Don't you just love it? I know there have to be nesting limits, but 15? Way too low. (And besides, Windows Forms shouldn't expose that nastiness - the code in SetBoundsCore could have checked that the message was relayed, and if not, updated the bounds 'manually').&lt;/p&gt;  &lt;p&gt;[ As Joel calls it, this is a good example of a &lt;a href=&quot;http://www.joelonsoftware.com/articles/LeakyAbstractions.html&quot; target=&quot;_blank&quot;&gt;&quot;Leaky Abstraction&quot;&lt;/a&gt; - that article by the way is well worth reading, if you haven't already. ]&lt;/p&gt;  &lt;p&gt;If you happen to experience this problem, you have two choices: either reduce the depth of your control hierarchy (the more ideal solution), or else derive &quot;fixed&quot; controls from each of the system ones that you use, as follows:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;     &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;FixedPanel&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;Panel&lt;/span&gt;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;protected&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; SetBoundsCore( &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; x, &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; y, &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; width, &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; height, &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt; specified )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;base&lt;/span&gt;.SetBoundsCore( x, y, width, height, specified );&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( specified != &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.None )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( ( specified &amp;amp; &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.X ) == &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.None )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; x = Left;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( ( specified &amp;amp; &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.Y ) == &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.None )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; y = Top;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( ( specified &amp;amp; &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.Width ) == &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.None )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; width = Width;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( ( specified &amp;amp; &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.Height ) == &lt;span style=&quot;color: #2b91af&quot;&gt;BoundsSpecified&lt;/span&gt;.None )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; height = Height;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( x != Left || y != Top || width != Width || height != Height )&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; UpdateBounds( x, y, width, height );&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;&amp;#160; }&lt;/p&gt;      &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;Ugly, but it (mostly) works.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I've managed to trim a few unneeded panels out of the deeper hierarchies in FeedGhost, and assuming testing goes OK, this issue will be fixed in the next release of FeedGhost.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Generating Shiny 3-D Images For Websites</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17827</link>
      <pubDate>Wed, 13 Feb 2008 18:03:54 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17827</guid>
      <description>
        	&lt;p&gt;We're currently in the process of re-launching our company website: here's one theme we came up with...&lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;160&quot; alt=&quot;www.binarycomponents.com&quot; src=&quot;http://www.feedghost.com/blogimages/Shiny3DImagesForYourWebsite_E34F/NewBC.png&quot; width=&quot;204&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;http://www.binarycomponents.com&quot;&gt;www.binarycomponents.com&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;...and we wanted to bring it a little bit more up-to-date with an eye-catching spread of a part of our portfolio.&lt;/p&gt; &lt;p&gt;I've used the 3-D screenshot effect before, notably on the &lt;a title=&quot;FeedGhost&quot; href=&quot;http://www.feedghost.com/&quot; target=&quot;_blank&quot;&gt;FeedGhost website&lt;/a&gt;, and although one image is simple enough in Photoshop, I've never been able to get it looking quite right with more than one.&lt;/p&gt; &lt;p&gt;Today however I decided to bite the bullet and get it sorted properly. To that end, I wrote a little WPF-3D application that lets you import images, move and rotate them, and view them from various angles, and finally render them with a shiny reflection. Here's a few examples:&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;209&quot; alt=&quot;Circular Fan&quot; src=&quot;http://www.feedghost.com/blogimages/Shiny3DImagesForYourWebsite_E34F/BC3.png&quot; width=&quot;450&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&#160;&lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;340&quot; alt=&quot;BinaryComponents Portfolio&quot; src=&quot;http://www.feedghost.com/blogimages/Shiny3DImagesForYourWebsite_E34F/appthumbs.png&quot; width=&quot;446&quot; border=&quot;0&quot; /&gt;&lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;194&quot; alt=&quot;Photos&quot; src=&quot;http://www.feedghost.com/blogimages/Shiny3DImagesForYourWebsite_E34F/BC2.png&quot; width=&quot;450&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&#160;&lt;/p&gt; &lt;p&gt;Once I've tidied this application up a little I'll put it on our &lt;a title=&quot;BinaryComponents Labs&quot; href=&quot;http://www.binarycomponents.com/Labs&quot; target=&quot;_blank&quot;&gt;labs&lt;/a&gt; page for download.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>CodingDesign</category>
				
    </item>
    
    <item>
      <title>Some WPF Work</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17825</link>
      <pubDate>Tue, 29 Jan 2008 13:57:40 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17825</guid>
      <description>
        	&lt;p&gt;I've been doing quite a bit of WPF (Windows Presentation Foundation) experimenting recently, on a project that will hopefully turn into another commercial product for BinaryComponents.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p align=&quot;center&quot;&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;240&quot; alt=&quot;Samtala1&quot; src=&quot;http://www.feedghost.com/blogimages/SomeWPFStuff_F916/Samtala1.png&quot; width=&quot;300&quot; border=&quot;0&quot; /&gt;&#160;&#160; &lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;240&quot; alt=&quot;Samtala2&quot; src=&quot;http://www.feedghost.com/blogimages/SomeWPFStuff_F916/Samtala2.png&quot; width=&quot;300&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;It's in very early stages as yet, which is why I'm showing tiny screenshots instead of full-size ones. (You can't see so many rough edges that way). All of the XAML, both content and style, is hand-coded by the way - learning Expression Blend is a job for the future. Data access is using LINQ, of course.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;I think I'm finally getting the hang of the WPF &quot;way&quot; - it's taking me a while to untrain myself from the WinForms modes of thought. If anyone's starting a new desktop application and can't decide whether to learn WPF or stick with WinForms - my advice is definitely to go for WPF - once it clicks, you won't want to go back. (Of course, whether you want to develop desktop applications is another question entirely).&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Naming Confusions in WPF</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17815</link>
      <pubDate>Thu, 29 Nov 2007 15:06:00 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17815</guid>
      <description>
        	&lt;p&gt;WPF provides a wide range of container controls that lay out their children in various ways (Grid, StackPanel, DockPanel, etc), but occasionally you need something slightly out-of-the-ordinary, and in those cases you have to write your own layout logic. For not-very-interesting reasons, I needed a container that would layout all its children on top of each other, using the full size of the parent container.&lt;/p&gt; &lt;p&gt;The usual method of achieving this is derive from the abstract class Panel, and implement your own MeasureOverride and ArrangeOverride methods. There's plenty of examples out there, but in most cases they assume that the layout is going to be at least partly dependent on the sizes of the child elements. Mine of course, isn't, so I wrote the following:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;&lt;p&gt;protected override Size MeasureOverride( Size availableSize )&lt;br /&gt;{&lt;/p&gt;&lt;p&gt;    // Error is here (missing code).&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&#160;&#160;&#160; return availableSize;&lt;br /&gt;} &lt;/p&gt;
&lt;p&gt;protected override Size ArrangeOverride( Size finalSize )&lt;br /&gt;{&lt;br /&gt;&#160;&#160;&#160; var rect = new Rect( finalSize ); 
&lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; foreach( UIElement child in InternalChildren )&lt;br /&gt;&#160;&#160;&#160; {&lt;br /&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; child.Arrange( rect );&lt;br /&gt;&#160;&#160;&#160; } 
&lt;/p&gt;&lt;p&gt;&#160;&#160;&#160; return finalSize;&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;...and it sort of worked, but only when expanding the control, not when shrinking. After half an hour of tearing my hair out, I finally found the answer in MSDN. (On a side note, it's a poor state of affairs when the official documentation is so bad that it's the last resort).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;UIElement.Measure()... Updates the DesiredSize of a UIElement.&quot;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Ah-ha! I should have &lt;em&gt;measured&lt;/em&gt; my children! In my mind, while I can guess that arrange will change something, I just assumed that measure was free of side-effects, and so could be skipped. It's not, and I think that's slightly misleading naming. (Unless perhaps WPF elements are quantum...) The solution of course was to iterate the children in MeasureOverride, and measure each one, throwing away the results.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Deleting Rows in LINQ-to-SQL</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17808</link>
      <pubDate>Tue, 06 Nov 2007 16:14:55 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17808</guid>
      <description>
        	&lt;p&gt;I spent a while this morning trying to figure out a rather strange error message while trying to delete data using LINQ, so I thought I'd pass on the answer.&lt;/p&gt; &lt;p&gt;Let's suppose we have two tables, Parent and Child, linked by a one-to-many foreign key relationship:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Parent - PK ParentId&lt;/p&gt; &lt;p&gt;Child - PK ChildId, FK OwnerParentId referenced Parent.ParentId&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Now let's suppose you want to delete a child row from the parent:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;parent.Children.Remove( child );&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The error you get, assuming your foreign key column is non-nullable, is:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;An attempt was made to remove a relationship between a Parent and a Child. However, one of the relationship's foreign keys (Child.OwnerParentId) cannot be set to null.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;After a fair amount of searching, I've found this is because LINQ's default behaviour is simply to try to &lt;strong&gt;unlink&lt;/strong&gt; the relationship by setting Child.OwnerParentId to null.&lt;/p&gt; &lt;p&gt;If you actually want to delete the child row instead, you'll need to amend your DBML file to specify a different DeleteOnNull rule. Right-click it and choose &quot;Open with...&quot; then &quot;XML Editor&quot;. Find the appropriate association (and note each one appears twice, once for each direction - you need to edit the one in the child table) and set DeleteOnNull:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&amp;lt;Association Name=&quot;Parent_Child&quot; Member=&quot;Parent&quot; AccessModifier=&quot;Internal&quot; ThisKey=&quot;OwnerParentId&quot; Type=&quot;Parent&quot; IsForeignKey=&quot;true&quot; &lt;strong&gt;DeleteOnNull=&quot;true&quot;&lt;/strong&gt; /&amp;gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Sorted!&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Why Is That Internal?</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17806</link>
      <pubDate>Mon, 05 Nov 2007 10:54:05 +0000</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17806</guid>
      <description>
        	&lt;p&gt;I'm a big fan of the .NET framework, so much so that for the past five years I haven't wanted to code in any other environment. Even so, sometimes I find myself getting frustrated with it - most recently when I was trying to get ASP.NET user controls (.ascx files) working from a different assembly (I mean come on - that's fairly basic - why won't ASP.NET let me do that?)&lt;/p&gt; &lt;p&gt;Since it's not a supported scenario, to get it to work I had to patch into the resource loading system, then fix up any field references and post-back events. Thanks to reflection I got it working in the end, but it's just so frustrating to be able to see the function I want to hook into in the call-stack or using &lt;a href=&quot;http://www.aisto.com/roeder/dotnet/&quot; target=&quot;_blank&quot;&gt;Reflector&lt;/a&gt;, but not be able to because that function has internal accessibility.&lt;/p&gt; &lt;p&gt;I was pretty grumpy by then, so I decided to look into something that's been bothering me for a while now: why, whenever you want to do something slightly out-of-the-ordinary, do you find yourself blocked by the framework and its private, internal, non-virtual design?&lt;/p&gt; &lt;p&gt;I decided to focus on the 'internal' problem and knocked up a little application that scans the public types in an assembly, and counts the number of public, internal, and private, fields and methods. (I'm lumping public and protected in the same count since they're both part of the public contract of a class, and I'm only considering exported types since there can be good reasons to have internal classes with internal methods. For non-.NET coders, internal types are public to types in the same assembly, and private outside, a cousin to 'friend' in C++). Here's what we get for a selection of framework assemblies:&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;348&quot; alt=&quot;System Assemblies - % Internal&quot; src=&quot;http://www.feedghost.com/blogimages/WhyIsThatInternal_C2FB/Internal.png&quot; width=&quot;644&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p&gt;Yikes! Some of those assemblies are comprised 15% - 20% of internal methods. How come the System-Drawing team managed a design with just 1% internal, but the System-Xml-Linq team felt they needed nearly 20%?&lt;/p&gt; &lt;p&gt;'Internal' breaks a class's modularity and encapsulation. If you feel another class ought to be able to access a method, use public. If not, that's private. If you're using internal, you're too lazy to create a decent design.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;strong&gt;When you have a lot of internal methods, you cease to have an assembly containing independent classes. You instead have a single, monolithic, assembly-sized class. You can't change anything without affecting every other class in your assembly.&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I'm not saying that you have to get to 0% internal methods, just that that accessibility should be reserved for unusual cases. Some framework teams seem able to manage it. We've managed it, albeit in a much smaller project - see the screenshot below. Why can't the other framework teams?&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px&quot; height=&quot;459&quot; alt=&quot;FeedGhost Assemblies - % Internal&quot; src=&quot;http://www.feedghost.com/blogimages/WhyIsThatInternal_C2FB/Internal2.png&quot; width=&quot;636&quot; border=&quot;0&quot; /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>AnnoyancesCoding</category>
				
    </item>
    
    <item>
      <title>Estimating Piracy Rates - IE7 Released Without WGA Checks</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17798</link>
      <pubDate>Sun, 07 Oct 2007 12:24:59 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17798</guid>
      <description>
        	&lt;p&gt;I noticed a few days back that Microsoft have announced that IE7 is to be released to everyone - without the usual WGA checks. Here's something they could do with the data they collect: estimate piracy rates.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;A&lt;/strong&gt;. Microsoft know how many people legally own Windows.&lt;br /&gt;&lt;strong&gt;B&lt;/strong&gt;. Microsoft know how many people upgraded to IE7 under the WGA checks. &lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;=&amp;gt; Roughly, the proportion of people who want to or can upgrade is &lt;strong&gt;B/A&lt;/strong&gt;. &lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;C&lt;/strong&gt;. Microsoft know how many EXTRA people upgraded after the WGA check was removed (they may have to wait a few months to make this more accurate).  &lt;blockquote&gt; &lt;p&gt;=&amp;gt; There are roughly &lt;strong&gt;C * A/B&lt;/strong&gt; pirated copies of Windows.&lt;/p&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Other</category>
				
    </item>
    
    <item>
      <title>Easier Threading: Software Transactional Memory: Part 4</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17791</link>
      <pubDate>Fri, 07 Sep 2007 17:30:56 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17791</guid>
      <description>
        	&lt;p&gt;&lt;/p&gt; &lt;p&gt;Last article I covered my implementation of software transactional memory in C#. If you&#160;haven't read&#160;those articles yet, in brief,&#160;it's a technique where we can write efficient, thread-safe client code without using having to think about locks or events - all isolation, atomicity and signaling is handled by a small set of common routines.&lt;/p&gt; &lt;p&gt;I've presented this technique, and the code, as&#160;the realization of an&#160;idea that could be taken further - I'm pretty sure it's not ready for production code yet.&#160;In this final article, I'll give a link to the source, and cover some pros and cons of this technique.&lt;/p&gt; &lt;p&gt;The articles and source will be kept up-to-date on:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href=&quot;http://www.binarycomponents.com/Labs&quot;&gt;http://www.binarycomponents.com/Labs&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;But for convenience, here's links to everything so far:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Part 1: &lt;a href=&quot;http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17787&quot; target=&quot;_blank&quot;&gt;The Problems with Locking&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Part 2: &lt;a href=&quot;http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17789&quot; target=&quot;_blank&quot;&gt;Atomicity and Isolation: That Reminds Me Of A Database&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Part 3: &lt;a href=&quot;http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17790&quot; target=&quot;_blank&quot;&gt;Implementation&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Source: &lt;a href=&quot;http://www.binarycomponents.com/Resources/Source/TransactionalMemory.zip&quot; target=&quot;_blank&quot;&gt;TransactionalMemory.zip&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Pros&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;Safety: Transactional values must be accessed inside a transaction. This is enforced by a runtime check.  &lt;li&gt;No deadlocks: All locks are taken by the implementation, not the client code. Locks are taken in a strict order.  &lt;li&gt;No explicit communication: Communication is handled by the implementation; the client only needs to rollback and wake-ups are handled automatically and efficiently.  &lt;li&gt;Fine-grained locking: Only those locks which need to be taken are taken, and for as short a time as possible.&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Cons&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;Copy overhead: When values are first accessed, or a transaction committed, values are copied. This would be unacceptable for large data-structures.  &lt;li&gt;Re-execute overhead: Code blocks that rollback must be re-run. If the block performs significant processing, this would waste CPU time.  &lt;li&gt;No side-effect checking: Code blocks should be free of side-effects, but this cannot be enforced in C#.&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Feedback&lt;/h3&gt; &lt;p&gt;If you have any comments on this technique, please let me know. I'd be particularly interested if anyone uses it in &quot;real&quot; code, as opposed to my simple examples. Additionally, if you're able to overcome any of the &quot;cons&quot; listed, I'd like to know that too.&lt;/p&gt; &lt;p&gt;If you find any bugs, please do let me know, and I'll update the source. (Any bugs in the implementation will of course go to show how bug-prone normal locking techniques are).&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Further Reading (And Listening)&lt;/h3&gt; &lt;p&gt;If you're interested in multi-threaded coding techniques, you might find the following .NET-related projects and shows interesting:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&quot;https://research.microsoft.com/~crusso/joins/index.htm&quot; target=&quot;_blank&quot;&gt;Joins Concurrency Library for C# 2.0&lt;/a&gt;  &lt;li&gt;&lt;a href=&quot;http://research.microsoft.com/Comega/&quot; target=&quot;_blank&quot;&gt;C? (Comega)&lt;/a&gt;  &lt;li&gt;.NET Rocks! shows about concurrency: &lt;a href=&quot;http://www.dotnetrocks.com/default.aspx?showNum=241&quot; target=&quot;_blank&quot;&gt;#241&lt;/a&gt;,&#160;&lt;a href=&quot;http://www.dotnetrocks.com/default.aspx?showNum=269&quot; target=&quot;_blank&quot;&gt;#269&lt;/a&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Easier Threading: Software Transactional Memory: Part 3</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17790</link>
      <pubDate>Thu, 06 Sep 2007 12:11:30 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17790</guid>
      <description>
        	&lt;p&gt;Previously I presented transactions as an alternative conceptual scheme to locking. In this article I'm going to examine an efficient implementation of software transactional memory.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Preamble&lt;/h3&gt; &lt;p&gt;Before I begin, I want to re-iterate that these ideas, and in particular the basics of the implementation, are drawn from the chapter &quot;Beautiful Concurrency&quot; by Simon Peyton Jones from &lt;a href=&quot;http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047/&quot; target=&quot;_blank&quot;&gt;this book&lt;/a&gt;. He described the Haskell version of software transactional memory; what I'm going to describe is my rendition of that into C#.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Source&lt;/h3&gt; &lt;p&gt;The complete source code, plus a few simple test applications, can be found at:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a title=&quot;http://www.binarycomponents.com/Resources/Source/TransactionalMemory.zip&quot; href=&quot;http://www.binarycomponents.com/Resources/Source/TransactionalMemory.zip&quot;&gt;http://www.binarycomponents.com/Resources/Source/TransactionalMemory.zip&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;You'll need Visual Studio 2008 Beta 2 if you want to compile this project.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Overview&lt;/h3&gt; &lt;p&gt;This implementation draws on the usual implementation of database transactions. When a transaction is begun, a &quot;log&quot; is created that will store the state related to the transaction. This state may be&#160;read, written, or&#160;discarded, without affecting the committed, valid memory. The transaction logs, together with the locks, events, and most of the logic is held in a manager class.&lt;/p&gt; &lt;p&gt;All transactional data is held in classes derived from TransactionalValue. The derived classes proxy all requests through the manager, so that any necessary checks can be made (for example, to check that they aren't accessed outside of a transaction), and so that the log can be read or written appropriately.&lt;/p&gt; &lt;p&gt;Code that acts on transactional values is represented by Actions. To save the hassle of creating a derived class for each block of transactional code, a DelegateAction is provided so that code may be written inline. The code in an action should be side-effect free since it may be executed more than once. The action returns success or failure depending on whether the block should be committed or rolled back. (Of course, just because the block wishes to be committed doesn't mean it will be).&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Locking&lt;/h3&gt; &lt;p&gt;Each transactional value is associated with one of a number of lock objects, and one of a number of events. Locks and events are allocated&#160;in turn as each transactional value is created.&#160;The lock is used whenever the real, committed value needs to be read or written. (This will occur on the first read or write of the value in a transaction, or when a transaction log is being verified and committed). The events are simple &quot;wake ups&quot; used to retry transactional code blocks after a rollback. All locking and wake-up logic is contained within the manager. When locks need to be taken, they are taken in strict order, so deadlocking is avoided.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;The Log&lt;/h3&gt; &lt;p&gt;The first time a particular transactional value is accessed within a transaction (either read or write), it is &quot;promoted&quot; to the log. In the log is stored the working value, together with the value that was initially read. Subsequent reads or writes to that value act on the working value in the log. The log is&#160;stored per-thread.&lt;/p&gt; &lt;p&gt;When the log is ready to be committed, it must first be verified for consistency. Failing verification results in a rollback and retry. Before verification (and possible commit), all locks associated with values in the log are locked. A log is verified if all of the stored original values are the same as the current master values. If verified, the master values can safely be overwritten by the log values.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Rollbacks&lt;/h3&gt; &lt;p&gt;If a transaction needs to be rolled back (either because the code block requested it, or because the log verification failed), the log is discarded, and the code block is scheduled for re-execution. Because the code is assumed to be free of side-effects, the only time the block could possibly succeed (having just failed) is when one of the values it has read during execution&#160;changes. To efficiently perform this wait, the manager waits on the events associated with the values in the log. These events are signaled when a log commits.&lt;/p&gt; &lt;p&gt;Explicitly requesting a rollback is a great way for threads to communicate. For example, in the &quot;Dining Philosophers&quot; sample, a rollback is requested if either fork is in use - the thread will be woken when one of the neighbours puts the fork down - and in the &quot;Producer/Consumer&quot; sample, a rollback is requested by the consumer if the buffer is empty - the thread will be woken when the producer adds a value. Note that none of this communication is explicitly stated in the client code - it just magically works.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;In the next and final article, I'll look at some pros and cons of this technique.&#160;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Easier Threading: Software Transactional Memory: Part 2</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17789</link>
      <pubDate>Wed, 05 Sep 2007 14:18:38 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17789</guid>
      <description>
        	&lt;p&gt;Last article I talked about the use of locks to solve threading issues, and how they problematic they are: necessary, but very low level. In this article, I'm going to imagine a different world...&lt;/p&gt; &lt;p&gt;Let's imagine that we can open a transaction, just as we might when using SQL, but for ordinary variables. Transactions have two important properties:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Atomicity&lt;/strong&gt;: Others can see the state before the transaction, the state after the transaction, but never the state part-way through. A transaction is all-or-nothing.  &lt;li&gt;&lt;strong&gt;Isolation&lt;/strong&gt;: Conversely, if you're working within a transaction, you can't see other's changes. You see a (consistent) snapshot of the state of system at the time of the start of the transaction.&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;And afterall, that consistency is&#160;what we're trying to achieve with locking.&#160;If we can get transactions working, we should be able to use them instead of locks.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;So let's imagine that this exists for memory, not just SQL databases. Our bank account problem from the previous article suddenly becomes very easy to solve:&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;class BankAccount
{
  public void Deposit( long change )
  {
    BEGIN TRANSACTION
    _amount += change;
    COMMIT TRANSACTION
  }

  private t_long _amount;
}

public static void Transfer( BankAccount a, BankAccount b, long amount )
{
  BEGIN TRANSACTION
  a.Deposit( -amount );
  b.Deposit( amount );
  COMMIT TRANSACTION
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Easy. Of course, we could never have that actual&#160;syntax in C#, but that's conceptually what we want to achieve.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;p&gt;Of course, one correct (but really bad) way of implementing this would be to have a single, global, lock, and to lock and unlock that as we enter and exit transactions. If we also checked that we were in a transaction before accessing a variable (and that's why I've changed the type to be &quot;t_long&quot; to imply that), then we have solved all three problems mentioned previously. Of course, that method doesn't scale very well: any contention on the lock, even if it was on different values, would block all other threads. It does at least demonstrate that the concept is good.&lt;/p&gt;
&lt;p&gt;So next article I'm going to describe a better way of implementing memory-transactions using optimistic locking. I'll also look into the&#160;transaction command I've not mentioned so far, ROLLBACK, and discover it's really useful.&#160;I have an actual working implementation of all this&#160;in C#, so at the end of these articles, I'll make the source available.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Easier Threading: Software Transactional Memory: Part 1</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17787</link>
      <pubDate>Tue, 04 Sep 2007 16:27:20 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17787</guid>
      <description>
        	&lt;p&gt;As I mentioned in a&#160;&lt;a href=&quot;http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17779&quot; target=&quot;_blank&quot;&gt;previous&#160;post&lt;/a&gt;, I've been reading through &quot;&lt;a href=&quot;http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047/&quot; target=&quot;_blank&quot;&gt;Beautiful Code: Leading Programmers Explain How They Think&lt;/a&gt;&quot;, and one chapter that really caught my attention was about Software Transactional Memory. What I'm about to present&#160;in this mini-series&#160;therefore is merely my take on an idea that greater minds than mine have come up with.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;The Problems with Locking&lt;/h3&gt; &lt;p&gt;I'm a C# / .NET programmer, and the staple multi-threaded construct is the lock block (which is basically a monitor or mutex):&lt;/p&gt; &lt;blockquote&gt;&lt;pre&gt;lock( _lockObject )
{
  SharedResource.Foo(); // Access a shared resource.
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;All fine and good, and you certainly can't do without them, but there's a bunch of problems with them:&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h3&gt;1. Locks Aren't Enforced&lt;/h3&gt;
&lt;p&gt;Since there's no necessary connection between the lock and the resource, it's possible to forget to lock:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;Thread_1
{
  lock( _lock )
  {
    SharedResource.Foo(); // Access a shared resource.
  }
}
 
Thread_2
{
  SharedResource.Foo(); // Access a shared resource.
  // Oops!
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;There's not even a runtime&#160;error here. That program is wrong, silently wrong, and difficult to debug.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h3&gt;2. Locks Don't Combine&lt;/h3&gt;
&lt;p&gt;Let's say we have a bank account class:&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;class BankAccount
{
  public void Deposit( long change )
  {
    lock( _lock )
    {
      _amount += change;
    }
  }

  private long _amount;
  private object _lock = new object();
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Then how do we write a thread-safe&#160;transfer method?&lt;/p&gt;
&lt;blockquote&gt;&lt;pre&gt;public static void Transfer( BankAccount a, BankAccount b, long amount )
{
  // This is incorrect:
  a.Deposit( -amount );
  b.Deposit( amount );
}
&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;What can I lock on to make this function correct?&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h3&gt;3. Locks Can Deadlock&lt;/h3&gt;
&lt;p&gt;If you're using more than one lock, you'd better get them in the right order, otherwise you're jammed. Getting into deadlock is easy; getting out is near-impossible.&lt;/p&gt;
&lt;p&gt;&#160;&lt;/p&gt;
&lt;h3&gt;The Cliff-Hanger&lt;/h3&gt;
&lt;p&gt;So locks are evil then. A necessary evil, but evil nonetheless. But we can hide them away...&lt;/p&gt;
&lt;p&gt;As a parting teaser before the following parts, here's my implementation of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Dining_philosophers&quot; target=&quot;_blank&quot;&gt;Dining Philosophers&lt;/a&gt; problem, written without any (obvious) locks:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Threading;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;namespace&lt;/span&gt; ConsoleTests&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; DiningPhilosophers&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; Run()&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Create fork values.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;for&lt;/span&gt;( var i = 0; i &amp;lt; _numPhilosophers; ++i )&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; _forks[i] = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; BinaryComponents.TransactionalMemory.Values.Boolean( &lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt; );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Create a thread for each philosopher.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;for&lt;/span&gt;( var i = 0; i &amp;lt; _numPhilosophers; ++i )&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;var&lt;/font&gt;&lt;/span&gt; pts = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ParameterizedThreadStart&lt;/span&gt;( RunPhilosopher );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;var&lt;/font&gt;&lt;/span&gt; thread = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Thread&lt;/span&gt;( pts );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; thread.Start( i );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; RunPhilosopher( &lt;span style=&quot;color: blue&quot;&gt;object&lt;/span&gt; data )&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&#160;&#160;&#160;&#160;&#160;&lt;font color=&quot;#0000ff&quot;&gt;var&lt;/font&gt; n = (&lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt;) data;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;var&lt;/font&gt;&lt;/span&gt; rnd = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;Random&lt;/span&gt;();&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;font color=&quot;#0000ff&quot;&gt;var&lt;/font&gt; leftFork = _forks[n];&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;font color=&quot;#0000ff&quot;&gt;var&lt;/font&gt; rightFork = _forks[( n + 1 ) % _numPhilosophers];&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;while&lt;/span&gt;( &lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt; )&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Console&lt;/span&gt;.WriteLine( &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;.Format( &lt;span style=&quot;color: #a31515&quot;&gt;&quot;Philosopher {0} is hungry...&quot;&lt;/span&gt;, n ) );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Try to grab the forks.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; BinaryComponents.TransactionalMemory.Manager.Execute( &lt;span style=&quot;color: blue&quot;&gt;delegate&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// If either fork we want is in use, then retry.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( leftFork.Value || rightFork.Value )&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Otherwise, grab them.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; leftFork.Value = &lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; rightFork.Value = &lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; } );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Eat for a while.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Console&lt;/span&gt;.WriteLine( &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;.Format( &lt;span style=&quot;color: #a31515&quot;&gt;&quot;Philosopher {0} is eating.&quot;&lt;/span&gt;, n ) );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Thread&lt;/span&gt;.Sleep( rnd.Next( 5000 ) );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Console&lt;/span&gt;.WriteLine( &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt;.Format( &lt;span style=&quot;color: #a31515&quot;&gt;&quot;Philosopher {0} puts down the forks and starts thinking.&quot;&lt;/span&gt;, n ) );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Drop the forks.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; BinaryComponents.TransactionalMemory.Manager.Execute( &lt;span style=&quot;color: blue&quot;&gt;delegate&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; {&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; leftFork.Value = &lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; rightFork.Value = &lt;span style=&quot;color: blue&quot;&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; } );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;//&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: green&quot;&gt;// Think for a while.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Thread&lt;/span&gt;.Sleep( rnd.Next( 5000 ) );&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;int&lt;/span&gt; _numPhilosophers = 5;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;static&lt;/span&gt; BinaryComponents.TransactionalMemory.Values.Boolean[] _forks = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; BinaryComponents.TransactionalMemory.Values.Boolean[_numPhilosophers];&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;&#160; }&lt;/p&gt;
&lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Silverlight Image Mashup Problems (And Solutions)</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17783</link>
      <pubDate>Tue, 21 Aug 2007 15:57:02 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17783</guid>
      <description>
        	&lt;p&gt;&lt;/p&gt; &lt;p&gt;(Actually, most of the solutions presented here apply to all kinds of mashups in Silverlight, not just images).&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Background&lt;/h3&gt; &lt;p&gt;We've officially started work on the online/web version of FeedGhost, and given that our expertise in mainly in .NET, we've decided to make it a Silverlight application. I've started work on the component that will take the messy HTML found in feeds and display it using Silverlight's subset of WPF. The process will be something like:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Convert the HTML to XHTML (or at least, XML - we won't be validating anything at this stage).  &lt;li&gt;Convert the XHTML to an intermediate format. This format will be simple and well-defined. CSS Styles will be expanded here.  &lt;li&gt;Render the intermediate format to WPF elements. This stage may be repeated if further layouts are required.&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Stage 1 has already been coded - you can read about its use in FeedGhost for Windows &lt;a href=&quot;http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17754&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Stage 3 involves the most unknowns for me, so I'm working on that right now.&lt;/p&gt; &lt;p&gt;One of the features I'm going to have implement is displaying images: an author can include an image (or rather, a link to an image) in his/her blog, and FeedGhost Online should be able to display it. Let's take the obstacles one by one...&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Cross-Site Scripting&#160;(XSS)&#160;Protection&lt;/h3&gt; &lt;p&gt;Silverlight protects against &lt;a href=&quot;http://en.wikipedia.org/wiki/Xss&quot; target=&quot;_blank&quot;&gt;cross-site scripting (XSS)&lt;/a&gt; attacks. I won't go into this in detail, but suffice to say, if your Silverlight application is hosted on &lt;em&gt;foo.com&lt;/em&gt; (for example), it can happily download resources that&#160;are also hosted&#160;on &lt;em&gt;foo.com&lt;/em&gt;, but it won't be able to download resources from &lt;em&gt;bar.com&lt;/em&gt;. This immediately presents us with a problem, since FeedGhost Online will be hosted on &lt;em&gt;feedghost.com&lt;/em&gt;, but the images will be coming from, well, anywhere.&lt;/p&gt; &lt;p&gt;Hopefully at some point Microsoft will allow developers to explicitly turn off aspects of XSS protection, but until that day, we need a work-around. There's various ways of achieving this, but I've chosen to use a proxy. Example: let's say my Silverlight application wants to download:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;http://www.example.com/image.jpg&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;It can't, so instead I code up a proxy and have the application&#160;ask for this instead:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;http://www.feedghost.com/imageproxy.ashx?uri=http://www.example.com/image.jpg&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;So long as my proxy delivers an image too, my Silverlight application will be able to download it.&lt;/p&gt; &lt;p&gt;(Don't bother trying either of those web addresses by the way, neither of them exist. Also, the parameter supplied should be encoded, but I haven't done that in this example for clarity).&lt;/p&gt; &lt;p&gt;The downside of this particular workaround is bandwidth - each image request is routed through your server, and you pay for each request twice: download and upload.&lt;/p&gt; &lt;p&gt;I'll show sample code for a proxy at the end of this article, but before then, we have more problems in the way.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Downloader Bugs&lt;/h3&gt; &lt;p&gt;Silverlight comes with a really helpful class, Downloader, that really simplifies downloading resources asynchronously, but without any kind of threading hassles. Unfortunately, in the latest Alpha Refresh release of Silverlight, a nasty bug crept in.&lt;/p&gt; &lt;p&gt;The bug manifests itself under the debugger, and prevents the Silverlight application from accessing resources that under normal hosting circumstances, it would be able to access. In other words, if I run my Silverlight application under the debugger thus:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;file:///C:/...somewhere.../Application.html&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;and it tries to access a resource:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;file:///C:/...somewhere.../Resources/Blah&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;it (incorrectly) fails.&lt;/p&gt; &lt;p&gt;The moral of this story is that if you can't get your Downloader to work correctly, try hosting your application under IIS and running it from localhost.&lt;/p&gt; &lt;p&gt;I've logged this particular bug with Microsoft:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a title=&quot;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=293772&quot; href=&quot;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=293772&quot;&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=293772&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Unsupported Image Formats&lt;/h3&gt; &lt;p&gt;Having worked almost exclusively with the .NET Framework for the past few years, I've become accustomed to it being able to handle any standard file I throw at it - any format, any encoding. Silverlight&#160;however runs on a cut-down version of the framework, and&#160;many features are missing. One of these&#160;missing features is support for the GIF file format. Since blog authors can choose to use any image format for their images, we need to solve this.&lt;/p&gt; &lt;p&gt;Luckily, the solution to this dovetails nicely with the XSS/proxy solution - when proxying images, simply convert GIFs to another file format.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Note&lt;/h3&gt; &lt;p&gt;Eventually, as well as using them in our online reader, we're planning to make the Silverlight flow-layout and&#160;HTML render components available for sale (together with the Silverlight river-view, tree, and list components that we'll need), but in the meantime, if you think you might be interested, please &lt;a href=&quot;mailto:stu@feedghost.com&quot; target=&quot;_blank&quot;&gt;contact me&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;h3&gt;Proxy Source Code&lt;/h3&gt; &lt;p&gt;Hopefully the following source code is enough to get you started with cross-site mashups. It's very simple; a production version would probably implement some kind of caching, and better error handling.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;ImageProxy.ashx&lt;/p&gt; &lt;blockquote&gt;&lt;code&gt; &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;background: #ffee62&quot;&gt;&amp;lt;%&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;@&lt;/span&gt; &lt;span style=&quot;color: #a31515&quot;&gt;WebHandler&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;Language&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&quot;C#&quot;&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;CodeBehind&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&quot;ImageProxy.ashx.cs&quot;&lt;/span&gt; &lt;span style=&quot;color: red&quot;&gt;Class&lt;/span&gt;&lt;span style=&quot;color: blue&quot;&gt;=&quot;Website.Content.Utility.ImageProxy&quot;&lt;/span&gt; &lt;span style=&quot;background: #ffee62&quot;&gt;%&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;/code&gt;&lt;/blockquote&gt; &lt;p&gt;ImageProxy.ashx.cs&lt;/p&gt; &lt;blockquote&gt;&lt;code&gt; &lt;div style=&quot;font-size: 10pt; background: white; color: black; font-family: consolas&quot;&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Data;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Web;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Collections;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Web.Services;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Web.Services.Protocols;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Net;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.IO;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Drawing;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;using&lt;/span&gt; System.Drawing.Imaging;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&lt;span style=&quot;color: blue&quot;&gt;namespace&lt;/span&gt; Website.Content.Utility&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;{&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;WebService&lt;/span&gt;( Namespace = &lt;span style=&quot;color: #a31515&quot;&gt;&quot;http://tempuri.org/&quot;&lt;/span&gt; )]&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; [&lt;span style=&quot;color: #2b91af&quot;&gt;WebServiceBinding&lt;/span&gt;( ConformsTo = &lt;span style=&quot;color: #2b91af&quot;&gt;WsiProfiles&lt;/span&gt;.BasicProfile1_1 )]&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;ImageProxy&lt;/span&gt; : &lt;span style=&quot;color: #2b91af&quot;&gt;IHttpHandler&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;void&lt;/span&gt; ProcessRequest( &lt;span style=&quot;color: #2b91af&quot;&gt;HttpContext&lt;/span&gt; context )&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;string&lt;/span&gt; uriText = context.Request[&lt;span style=&quot;color: #a31515&quot;&gt;&quot;uri&quot;&lt;/span&gt;];&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Uri&lt;/span&gt; uri;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( !&lt;span style=&quot;color: #2b91af&quot;&gt;Uri&lt;/span&gt;.TryCreate( uriText, &lt;span style=&quot;color: #2b91af&quot;&gt;UriKind&lt;/span&gt;.Absolute, &lt;span style=&quot;color: blue&quot;&gt;out&lt;/span&gt; uri ) )&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;HttpException&lt;/span&gt;( 404, &lt;span style=&quot;color: #a31515&quot;&gt;&quot;Bad URL parameter.&quot;&lt;/span&gt; );&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;try&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;WebRequest&lt;/span&gt; request = &lt;span style=&quot;color: #2b91af&quot;&gt;WebRequest&lt;/span&gt;.Create( uri );&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;WebResponse&lt;/span&gt; response = request.GetResponse();&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; context.Response.ContentType = response.ContentType;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Stream&lt;/span&gt; stream = response.GetResponseStream();&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;Image&lt;/span&gt; image = &lt;span style=&quot;color: #2b91af&quot;&gt;Image&lt;/span&gt;.FromStream( stream );&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;ImageFormat&lt;/span&gt; format = image.RawFormat;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;if&lt;/span&gt;( &lt;span style=&quot;color: blue&quot;&gt;object&lt;/span&gt;.Equals( image.RawFormat, &lt;span style=&quot;color: #2b91af&quot;&gt;ImageFormat&lt;/span&gt;.Gif ) )&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; format = &lt;span style=&quot;color: #2b91af&quot;&gt;ImageFormat&lt;/span&gt;.Png;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &#160; context.Response.ContentType = &lt;span style=&quot;color: #a31515&quot;&gt;&quot;image/png&quot;&lt;/span&gt;;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: #2b91af&quot;&gt;MemoryStream&lt;/span&gt; ms = &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;MemoryStream&lt;/span&gt;();&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; image.Save( ms, format );&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; ms.WriteTo( context.Response.OutputStream );&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; response.Close();&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;catch&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;throw&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;new&lt;/span&gt; &lt;span style=&quot;color: #2b91af&quot;&gt;HttpException&lt;/span&gt;( 404, &lt;span style=&quot;color: #a31515&quot;&gt;&quot;Failed to process image.&quot;&lt;/span&gt; );&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;bool&lt;/span&gt; IsReusable&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;get&lt;/span&gt;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; {&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; &#160; &lt;span style=&quot;color: blue&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: blue&quot;&gt;true&lt;/span&gt;;&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; &#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;&#160; }&lt;/p&gt; &lt;p style=&quot;margin: 0px&quot;&gt;}&lt;/p&gt;&lt;/div&gt;&lt;/code&gt;&lt;/blockquote&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Book Recommendation: Beautiful Code: Leading Programmers Explain How They Think</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17779</link>
      <pubDate>Mon, 13 Aug 2007 19:16:34 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17779</guid>
      <description>
        	&lt;p&gt;&lt;img style=&quot;border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 20px 10px 0px; border-right-width: 0px&quot; alt=&quot;Beautiful Code: Leading Programmers Explain How They Think&quot; src=&quot;http://www.feedghost.com/blogimages/BookRecommendationBeautifulCode_10C16/Beauty.jpg&quot; align=&quot;left&quot; border=&quot;0&quot; /&gt; I bought this book on a whim, and now, even though I'm only halfway through, I can thoroughly recommend it to any programmer.&lt;/p&gt; &lt;p&gt;&lt;b&gt;&lt;a href=&quot;http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047/&quot; target=&quot;_blank&quot;&gt;Beautiful Code: Leading Programmers Explain How They Think&lt;/a&gt;&lt;/b&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&#160;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;It's not a book of facts or techniques, rather&#160;it's thirty-odd &quot;presentations&quot; by different authors about the code they think is most beautiful. If you're anything like me you're not going to agree with 100% of these, and in fact I thought one chapter involving FORTRAN was horrific ugly code, but it will definitely get you thinking.&lt;/p&gt; &lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt; &lt;p&gt;Why you might want this book:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you've been working exclusively in one technology for a while&#160;(.NET, in my case), this book presents languages and environments of all kinds. Getting stuck in a rut is all too easy. &lt;li&gt;If you think you've got nothing left to learn, well, you &lt;em&gt;really&lt;/em&gt; need this book.  &lt;li&gt;If you've resigned yourself to the idea that certain aspects of programming are just facts of life, this book is full of radical new ways of thinking.&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;And if you're still not convinced, all author royalties from this book&#160;will be donated to Amnesty International.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Coding</category>
				
    </item>
    
    <item>
      <title>Breaking Changes in Orcas</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17768</link>
      <pubDate>Wed, 01 Aug 2007 15:02:54 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17768</guid>
      <description>
        	&lt;p&gt;Having been using Visual Studio 2008 &quot;Codename Orcas&quot; Beta 1 (breathe)&#160;for a while now, I was excited to see that &lt;a href=&quot;http://blogs.msdn.com/somasegar/archive/2007/07/26/announcing-the-release-of-visual-studio-2008-beta-2-net-fx-3-5-beta-2-and-silverlight-1-0-rc.aspx&quot; target=&quot;_blank&quot;&gt;Beta 2 is now available&lt;/a&gt;. These betas are stable, have some great new features, and are available as Virtual PC images (if like me you can't risk breaking a work machine), so there's really no excuse not to give it a try.&lt;/p&gt; &lt;p&gt;Unfortunately, I've hit two big breaking changes upgrading from Beta 1 to Beta 2, which is surprising given Microsoft's usual commitment to backwards-compatibility; hopefully this won't be the shape of things to come.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;Firstly, double-clicking any solution (.SLN) files created in Beta 1 doesn't do anything. The trick is to load it up into Notepad and change the line:&lt;/p&gt; &lt;blockquote&gt;&lt;code&gt; &lt;p&gt;Microsoft Visual Studio Solution File, Format Version 10.00&lt;br /&gt;# Visual Studio Codename Orcas&lt;/p&gt;&lt;/code&gt;&lt;/blockquote&gt; &lt;p&gt;to:&lt;/p&gt; &lt;blockquote&gt;&lt;code&gt; &lt;p&gt;Microsoft Visual Studio Solution File, Format Version 10.00&lt;br /&gt;# Visual Studio 2008&lt;/p&gt;&lt;/code&gt;&lt;/blockquote&gt; &lt;p&gt;I can't see any reason why the old format couldn't have been detected or upgraded in this situation.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;Secondly, and far more seriously, if you've previously created any LINQ-to-SQL schema files (.DBML), well, they're just junk now. The file format has changed and I can't see any way of upgrading from the old to the new. I'm glad Microsoft aren't sticking with sub-optimal designs just for backwards-compatibility, but if they want us to really get stuck into the betas, especially in key new feature areas, then upgrade paths are a must.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>AnnoyancesCoding</category>
				
    </item>
    
    <item>
      <title>An Interesting Find: ProductWiki</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17765</link>
      <pubDate>Wed, 25 Jul 2007 18:42:09 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17765</guid>
      <description>
        	&lt;p&gt;Now this isn't a new website by any means (although it is new to me), but it tweaked my interest. ProductWiki&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a title=&quot;http://www.productwiki.com/&quot; href=&quot;http://www.productwiki.com/&quot;&gt;http://www.productwiki.com/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;aims to be &quot;the most comprehensive product information resource supported by a passionate community&quot;, and it's a really nice idea: a review site in the form of a wiki. It does look like a fair few of the products are just the manufacturer's blurb with no actual independent review, HOWEVER if that bothers you,&#160;since it's a wiki you can go and add your voice.&lt;/p&gt; &lt;p&gt;(And yes, I have &lt;a href=&quot;http://www.productwiki.com/feedghost&quot; target=&quot;_blank&quot;&gt;added FeedGhost&lt;/a&gt; to the list. Feel free to go and be as critical as you like).&lt;/p&gt; &lt;p&gt;Another nice aspect of this site is that it seems to be under active moderation - there's nothing so depressing as visiting a &quot;community content&quot; site only to discover it's nothing more than a billboard for spammers. Not long after I posted my entry, I received a couple of questions from one of the founders of the site, so it looks like someone &quot;official&quot; is keeping an eye on things).&lt;/p&gt; &lt;p&gt;One little feature they might consider adding is &quot;reviews needed&quot;: let's say I search for a particular product, and it isn't in their database, perhaps they could tally those and present the most searched for as &quot;needing reviews&quot;. They do say there's a hundred times as many content-consumers as content-producers, and that could be a nice way of leading people into creating reviews.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Other</category>
				
    </item>
    
    <item>
      <title>I'm Moving</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17759</link>
      <pubDate>Thu, 12 Jul 2007 14:07:35 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17759</guid>
      <description>
        	&lt;p&gt;Emma and I are moving house tomorrow (finally), so I'll be out of contact for a while. Hopefully the internets should be re-connected on Tuesday, but it could be as long as two weeks.&lt;/p&gt; &lt;p&gt;In the meantime, if you need to contact me, please email Lee instead and he'll pass on any messages.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>Other</category>
				
    </item>
    
    <item>
      <title>Why Are Entity-Relationship Diagrams So Unintuitive?</title>
      <link>http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17758</link>
      <pubDate>Sat, 07 Jul 2007 20:15:01 +0100</pubDate>
      <guid isPermaLink="true">http://www.feedghost.com/Blogs/BlogEntry.aspx?EntryId=17758</guid>
      <description>
        	&lt;p&gt;I have a real problem with entity-relationship diagrams. I can never remember which way around is which.&lt;/p&gt; &lt;p&gt;Quick, answer me this: which side in the following&#160;is the parent ('one'), and which is the child ('many')?&lt;/p&gt; &lt;p&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;58&quot; alt=&quot;Which is which?&quot; src=&quot;http://www.feedghost.com/blogimages/WhyAreEntityRelationshipDiagramsSoUnintu_11B64/ParentOrChild.png&quot; width=&quot;469&quot; border=&quot;0&quot; /&gt; &lt;/p&gt; &lt;p&gt;What is the arrow pointing to? What does the diamond mean? There's no mnemonic that I can find there.&lt;/p&gt; &lt;p&gt;(If you can't remember the answer, and I don't blame you if that's the case, the 'parent' is on the left, and the arrow points to the 'child' on the right).&lt;/p&gt; &lt;p&gt;Just to make absolutely sure I can't remember, whoever standardized these diagrams choose to have&#160;arrows pointing 'downwards' on E-R diagrams, but 'upwards' on class-hierarchy diagrams.&lt;/p&gt; &lt;p&gt;It's not even as if my inability to remember&#160;is from lack of experience;&#160;the last commercial system I worked on had perhaps 200 tables, and I had a (minor) hand in the coding of the actual custom object-relational system itself.&lt;/p&gt; &lt;p&gt;&#160;&lt;/p&gt; &lt;p&gt;I propose the following: drop those dumb diamonds that don't mean anything, and standardize on crow's feet diagrams:&lt;/p&gt; &lt;p&gt;&lt;img style=&quot;border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px&quot; height=&quot;58&quot; alt=&quot;That's better!&quot; src=&quot;http://www.feedghost.com/blogimages/WhyAreEntityRelationshipDiagramsSoUnintu_11B64/ParentChildBetter.png&quot; width=&quot;469&quot; border=&quot;0&quot; /&gt;&#160;&lt;/p&gt; &lt;p&gt;One... to many. It speaks for itself. I'll even let you add bars and zeros to clarify the exact constraints if you feel you have to.&#160;Who's with me?&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.feedghost.com/?ref=blogs&quot;&gt;&lt;img src=&quot;http://www.feedghost.com/Promo/Images/Banner-632x153-White.png&quot; alt=&quot;FeedGhost - Professional RSS Reading&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
      </description>
      
			<category>AnnoyancesCoding</category>
				
    </item>
    
  </channel>
</rss>