<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-8081372847405402819</atom:id><lastBuildDate>Mon, 07 Oct 2024 04:49:29 +0000</lastBuildDate><category>C#</category><category>SQL Server</category><category>.Net</category><category>ASP.Net</category><category>Best Practice</category><category>Deadlocks</category><category>Error Handling</category><category>Java</category><category>jQuery</category><category>.Net 3.5</category><category>AJAX</category><category>Asynchronous</category><category>Blogging</category><category>Data Access</category><category>Design</category><category>UI</category><category>Visual Basic</category><title>Iain Hoult</title><description></description><link>http://iainhoult.blogspot.com/</link><managingEditor>noreply@blogger.com (Iain Hoult)</managingEditor><generator>Blogger</generator><openSearch:totalResults>19</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-5809734922517603745</guid><pubDate>Wed, 29 Feb 2012 10:08:00 +0000</pubDate><atom:updated>2012-02-29T10:08:00.388+00:00</atom:updated><title>We’re Hiring</title><description>&lt;p&gt;&lt;a href=&quot;http://www.openprojects.co.uk/&quot;&gt;Open Projects&lt;/a&gt; is a software house based in Nottingham UK, specialising in software for the newspaper/magazine circulation industry.&amp;nbsp; There are vacancies for two new people to join the team.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A &lt;strong&gt;developer&lt;/strong&gt; with skills in VB.Net, C#, ASP and SQL to work on Windows, web and mobile solutions.  &lt;li&gt;An &lt;strong&gt;IT Support &lt;/strong&gt;professional to handle second line support and to make sure none of the servers are on fire.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;For more details and how to apply, please go to the &lt;a href=&quot;http://bit.ly/eYq5BL&quot;&gt;Open Projects Careers&lt;/a&gt; page.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2012/02/were-hiring.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-7990642447921548961</guid><pubDate>Mon, 06 Jun 2011 20:53:00 +0000</pubDate><atom:updated>2011-06-06T21:53:04.743+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Visual Basic</category><title>How to Convert Strings to Integers in Visual Basic</title><description>&lt;p&gt;While recently reviewing a piece of code, I managed to spot three different methods being used for converting values stored in objects or strings into Integers.&amp;nbsp; This is where Visual Basic takes the record for having the most methods for performing the same operation.&amp;nbsp; Thinking about it I realised that I could name six different ways of converting strings to integers in Visual Basic…  &lt;p&gt;This post is a &quot;back to basics&quot; investigation into which way is best to convert to an Integer.  &lt;p&gt;Meet the methods:  &lt;h3&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/s2dy91zy(v=VS.100).aspx&quot; target=&quot;_blank&quot;&gt;CInt&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/4x2877xb(v=VS.100).aspx&quot; target=&quot;_blank&quot;&gt;CType&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/z1497ek4.aspx&quot; target=&quot;_blank&quot;&gt;Int&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/sf1aw27b.aspx&quot; target=&quot;_blank&quot;&gt;Convert.Int32&lt;/a&gt;, &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx&quot; target=&quot;_blank&quot;&gt;Integer.Parse&lt;/a&gt;, &amp;amp; &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/f02979c7(v=VS.100).aspx&quot; target=&quot;_blank&quot;&gt;Integer.TryParse&lt;/a&gt;&lt;/h3&gt; &lt;p&gt;CInt, CType and Int belong to the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.aspx&quot; target=&quot;_blank&quot;&gt;Microsoft.VisualBasic&lt;/a&gt; namespace.&amp;nbsp; Convert.Int32, Integer.Parse and Integer.TryParse are from the main body of the .Net Framework.  &lt;p&gt;To find the best way of converting a string to an integer I have run each of the methods through a series of tests; the speed of each method, its ability to round number, handle Nothing (null) and completely invalid values.  &lt;h3&gt;&amp;nbsp;&lt;/h3&gt; &lt;h3&gt;Test 1 – Speed&lt;/h3&gt; &lt;p&gt;In order to find the fastest method of converting a string to an integer each method was put through its paces converting the string “100” into an integer. To be able to see the difference in timings the operation was performed 100 million times. Each test run was carried out multiple times to achieve an average timing. Each batch of test runs were performed against three different version of the .Net Frameworks, 2.0, 3.5 and 4.0.  &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjI6Kg6OrhiLg5Pn5StRbodR6RpZGgeinuEmc2j6Bq8sjuH_IDSMMlwjsnGPKEK4nK8ARwgrHlCkDXSjcFtsmnnodxDQCiMhyphenhyphenku2idq5ECbT5_VP3hJm49OMVSCrP5987VGbRgHLMbriKE7/s1600-h/clip_image002%25255B6%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px&quot; title=&quot;clip_image002&quot; border=&quot;0&quot; alt=&quot;clip_image002&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8Ecwdbidi27iak7EM5HGwfL_1ysbNk9W2Tcez9WjwHWZ5gMelkBqSQAns0HrQTuBdKVPjDfomV6s36TESbbf5__egDZcrJg4y_rkd0d9dk-dB7zb_2lnOlwgeOeN_V5-PLiRQ51Rdz_vb/?imgmax=800&quot; width=&quot;611&quot; height=&quot;460&quot;&gt;&lt;/a&gt;  &lt;p&gt;&lt;font size=&quot;1&quot;&gt;(These timings are specific to my PC and should only be used for comparison with each other)&lt;/font&gt;  &lt;p&gt;The fastest method for .Net 2.0 and .Net 3.5 is Integer.Parse at 13.12 seconds and 13.23 seconds respectively, but is overtaken for .Net 4.0 by Integer.TryParse at 13.19 seconds.  &lt;p&gt;It is nice to know that using the TryParse method does not mean you are getting the performance hit you might imagine for the extra checking. (During testing a Boolean variable was being set to the result of the parse test).  &lt;p&gt;CInt, CType and Int performed badly in comparison to the other methods. This is conceivably due to these methods being there for backwards compatibility with old VB6 code, although as you will see in the next few tests they do more than the other methods.  &lt;p&gt;&amp;nbsp; &lt;h3&gt;Test 2 - Rounding&lt;/h3&gt; &lt;p&gt;Sometime it is desirable to round values that are not whole numbers into integers, for this test each method was passed “0.5” and “0.6” to determine if it could successfully convert the value to an integer, and whether it would round the number up or down.&lt;/p&gt; &lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;459&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;Method&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;0.5&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;0.6&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;CInt&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;1&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Convert.ToInt32&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;Exception&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;Exception&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;CType&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;1&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Int&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Integer.Parse&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;Exception&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;Exception&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Integer.TryParse&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;123&quot;&gt; &lt;p&gt;Failed&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;129&quot;&gt; &lt;p&gt;Failed&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Only the Microsoft.VisualBasic methods handled the test, the others threw exceptions apart from Integer.TryParse which, being designed for this scenario, reported a failure.  &lt;p&gt;Also it is interesting to note that Int will always returns the integer portion of the number, and so always rounds down for positive numbers and up for negative numbers. In researching this post I came across, if you can believe it, a seventh method of converting a string to an integer called &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/td07wybb(v=VS.100).aspx&quot; target=&quot;_blank&quot;&gt;Fix&lt;/a&gt;, which is very similar to Int but handles negative numbers differently.  &lt;p&gt;&amp;nbsp; &lt;h3&gt;Test 3 – Nothing (null)&lt;/h3&gt; &lt;p&gt;These are the results from attempting to convert a string set to Nothing into an integer.&lt;/p&gt; &lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;Method&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;Result&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;CInt&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Convert.ToInt32&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;CType&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;0&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Int&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;ArgumentNullException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Integer.Parse&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;ArgumentNullException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Integer.TryParse&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;Failed (0)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Interestingly the first three methods consider Nothing to be the same as zero, while once again Integer.TryParse rejects the value.  &lt;p&gt;&amp;nbsp; &lt;h3&gt;Test 4 – Invalid Integer&lt;/h3&gt; &lt;p&gt;Strings can of course contain text as well as numbers, the following results are when attempting to convert the string “abc” into an integer.&lt;/p&gt; &lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;Method&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;&lt;font size=&quot;2&quot;&gt;Result&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;CInt&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;InvalidCastException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Convert.ToInt32&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;FormatException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;CType&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;InvalidCastException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Int&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;InvalidCastException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Integer.Parse&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;FormatException&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;&lt;b&gt;Integer.TryParse&lt;/b&gt;&lt;/p&gt;&lt;/td&gt; &lt;td valign=&quot;top&quot; width=&quot;205&quot;&gt; &lt;p&gt;Failed&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Well I think from these results that it is fairly obvious that the language designers do not think it is a good idea to be able to pass any old string into an integer conversion. I agree, I would prefer my applications to &lt;a href=&quot;http://iainhoult.blogspot.com/2008/04/phrases-to-develop-by.html&quot; target=&quot;_blank&quot;&gt;fail fast&lt;/a&gt; rather than perhaps silently returns zeros when passed random text (as with Nothing above).  &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;h3&gt;Overall Results&lt;/h3&gt; &lt;p&gt;So which is best and why? Well it all comes down to how you are going to be using the function and what sort of data you want the function to handle.  &lt;p&gt;Unless you want the specific rounding abilities of Int then I can’t see any reason to ever use it. It performed badly against every test, making it the worst overall.  &lt;p&gt;If you need speed then you should ignore the Microsoft.VisualBasic methods, as they are at least twice as slow as the others.  &lt;p&gt;If you need to handle general rounding then CInt and CType are the only functions for you.  &lt;p&gt;If the data being presented for conversion may not be an integer, then use Integer.TryParse to successfully determine this without throwing an exception, in the fastest time. The only catch with this method is that you need to remember to handle the function passing back a failure result.  &lt;p&gt;Finally if you want the speed without the extra coding complexity that goes with handling the result from Integer.TryParse, the Integer.Parse looks best.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2011/06/how-to-convert-strings-to-integers-in.html</link><author>noreply@blogger.com (Iain Hoult)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8Ecwdbidi27iak7EM5HGwfL_1ysbNk9W2Tcez9WjwHWZ5gMelkBqSQAns0HrQTuBdKVPjDfomV6s36TESbbf5__egDZcrJg4y_rkd0d9dk-dB7zb_2lnOlwgeOeN_V5-PLiRQ51Rdz_vb/s72-c?imgmax=800" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-1266865249370180868</guid><pubDate>Fri, 13 May 2011 16:46:00 +0000</pubDate><atom:updated>2011-05-13T17:46:29.274+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Deadlocks</category><category domain="http://www.blogger.com/atom/ns#">SQL Server</category><title>Creating Deadlocks</title><description>&lt;p&gt;I wrote a post a while ago on &lt;a href=&quot;http://iainhoult.blogspot.com/2010/11/deadlock-handling.html&quot; target=&quot;_blank&quot;&gt;how to handle database deadlocks in your code&lt;/a&gt;, where I described how to programmatically detect and handle your code being chosen as the deadlock victim by SQL Server.&lt;br&gt;Running up against some deadlocking issues recently, I needed a way to reliably produce a deadlock so that I could test various scenarios.&amp;nbsp; I thought it might be useful to someone who needed to do the same thing, so this is what I did.&lt;/p&gt; &lt;h5&gt;Step 1 – Create the resources to lock&lt;/h5&gt; &lt;p&gt;To begin with we need two tables and data that we can lock.&amp;nbsp; (This is a prerequisite to actually producing the deadlock.)&lt;/p&gt;&lt;pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=create&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;create&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=table&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;table&lt;/a&gt; ResourceA (DataFieldA &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=int&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;int&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=not&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;not&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=null&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;null&lt;/a&gt;)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=insert&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;insert&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=into&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;into&lt;/a&gt; ResourceA (DataFieldA) &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=values&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;values&lt;/a&gt; (1)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=create&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;create&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=table&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;table&lt;/a&gt; ResourceB (DataFieldB &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=int&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;int&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=not&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;not&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=null&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;null&lt;/a&gt;)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=insert&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;insert&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=into&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;into&lt;/a&gt; ResourceB (DataFieldB) &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=values&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;values&lt;/a&gt; (1)&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;Now we need a method of getting Process 1 to lock Resource A while wanting Resource B, and at the same time having Process 2 lock Resource B while wanting Resource A.&lt;/p&gt;
&lt;h5&gt;Step 2 – Process One to Lock the data&lt;/h5&gt;&lt;pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=begin&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;begin&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=tran&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;tran&lt;/a&gt; Process1
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=update&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;update&lt;/a&gt; ResourceA &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=set&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;set&lt;/a&gt; DataFieldA = 2
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=waitfor&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;waitfor&lt;/a&gt; delay &#39;&lt;span style=&quot;color: #8b0000&quot;&gt;00:00:05&lt;/span&gt;&#39;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=update&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;update&lt;/a&gt; ResourceB &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=set&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;set&lt;/a&gt; DataFieldB = 2
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=commit&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;commit&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=tran&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;tran&lt;/a&gt; Process1&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;What happens here is that Process 1 locks Resource A, then while the lock is still being held there is a delay which gives us enough time to execute step 3, then Process 1 tries to get a lock on Resource B&lt;br&gt;&lt;/p&gt;
&lt;h5&gt;Step 3 – Process Two to Deadlock&lt;/h5&gt;
&lt;p&gt;While Process 1 is delayed after locking Resource A, we can execute Process 2 which will lock Resource B before Process 1 can get to it.&lt;/p&gt;&lt;pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=begin&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;begin&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=tran&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;tran&lt;/a&gt; Process2
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=update&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;update&lt;/a&gt; ResourceB &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=set&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;set&lt;/a&gt; DataFieldB = 3
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=update&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;update&lt;/a&gt; ResourceA &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=set&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;set&lt;/a&gt; DataFieldA = 3
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=commit&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;commit&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=tran&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;tran&lt;/a&gt; Process2&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;This will cause a deadlock and result in one of our two processes being rolled back.&amp;nbsp; The actual process that is chosen as the deadlock victim, will be selected based on which one SQL Server determines is the easiest to rollback.&lt;br&gt;So we have got to the point where we can create a deadlock, but we need a way of picking the process that we want to be rolled back.&amp;nbsp; This is achieved by setting the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms186736.aspx&quot; target=&quot;_blank&quot;&gt;deadlock priority&lt;/a&gt; on Process 1, to specify that it should not be chosen.&lt;/p&gt;&lt;pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=SET&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;SET&lt;/a&gt; DEADLOCK_PRIORITY HIGH
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=begin&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;begin&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=tran&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;tran&lt;/a&gt; Process1
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=update&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;update&lt;/a&gt; ResourceA &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=set&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;set&lt;/a&gt; DataFieldA = 2
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=waitfor&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;waitfor&lt;/a&gt; delay &#39;&lt;span style=&quot;color: #8b0000&quot;&gt;00:00:05&lt;/span&gt;&#39;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=update&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;update&lt;/a&gt; ResourceB &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=set&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;set&lt;/a&gt; DataFieldB = 2
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=commit&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;commit&lt;/a&gt; &lt;a style=&quot;color: #0000ff&quot; href=&quot;http://search.microsoft.com/default.asp?so=RECCNT&amp;amp;siteid=us%2Fdev&amp;amp;p=1&amp;amp;nq=NEW&amp;amp;qu=tran&amp;amp;IntlSearch=&amp;amp;boolean=PHRASE&amp;amp;ig=01&amp;amp;i=09&amp;amp;i=99&quot;&gt;tran&lt;/a&gt; Process1&lt;/pre&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;Now Process 2 will consistently be chosen as the deadlock victim, giving you a reliable way of creating deadlocks in your database. 
  </description><link>http://iainhoult.blogspot.com/2011/05/creating-deadlocks.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-670884115414343153</guid><pubDate>Wed, 16 Feb 2011 16:08:00 +0000</pubDate><atom:updated>2011-02-16T16:08:28.544+00:00</atom:updated><title>Vacancy for Junior Developer</title><description>&lt;p&gt;&lt;a href=&quot;http://www.openprojects.co.uk/&quot;&gt;Open Projects&lt;/a&gt; are looking to hire a new Junior Developer, primarily to do .Net development. &lt;p&gt;If you live in or around Nottingham, and you are interested in joining a team where you will learn a wide variety of skills doing a whole host of different jobs, why not send in your CV. &lt;p&gt;Full details can be found &lt;a href=&quot;http://bit.ly/eYq5BL&quot;&gt;here&lt;/a&gt;&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2011/02/vacancy-for-junior-developer.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-1587671115187990283</guid><pubDate>Thu, 27 Jan 2011 20:42:00 +0000</pubDate><atom:updated>2011-01-27T20:42:53.548+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">jQuery</category><title>Using jQuery with frames</title><description>&lt;p&gt;I’ve been having lots of fun recently getting my jQuery skills up to speed, one of the things that I found tricky, and hard to find any information on, was how to use jQuery with frames.  &lt;p&gt;As there isn’t much out there on the subject I thought it may be useful to someone if I wrote a quick blog post on my findings.  &lt;p&gt;The good news is that it pretty easy to get jQuery to work with frames, the main obstacle I ran up against when trying to find out how to do it were “helpful suggestions” online that didn’t actually work. I have a suspicion that it might be down to using IE8, as I had another IE/jQuery issue, but that’s post for another day.  &lt;p&gt;To start with you need a page containing your &lt;a href=&quot;http://www.w3.org/TR/html4/present/frames.html&quot; target=&quot;_blank&quot;&gt;frameset&lt;/a&gt;.&amp;nbsp; The example frameset below contains two frames, one on the left and one on the right. Note that each frame has an “id” attribute.&lt;/p&gt;&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 594px; padding-right: 5px; height: 108px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;frameset&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;cols&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;160,*&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;border&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;frame&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;left&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;scrolling&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;no&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;noresize&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;left.aspx&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;frame&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;right&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;noresize&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;right.htm&quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;border&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;frameset&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;The jQuery will be in the frame on the left (in “left.aspx”), while we will be acting upon the frame on the right (“right.htm”). 
&lt;p&gt;To change a setting on the other frame we use the second argument (context) in the jQuery function to specify the frame. The example below will change the text in a paragraph (“p”) tag.&lt;/p&gt;&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 593px; padding-right: 5px; height: 52px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;$(&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;p&lt;/span&gt;&quot;, &lt;span style=&quot;color: #0000ff&quot;&gt;window&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;parent&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;frames&lt;/span&gt;[&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;right&lt;/span&gt;&quot;].&lt;span style=&quot;color: #0000ff&quot;&gt;document&lt;/span&gt;).text(&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;something new&lt;/span&gt;&quot;);&lt;/pre&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;window&lt;/span&gt;=the current frame &lt;br&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;parent&lt;/span&gt;=the frameset &lt;br&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;frames&lt;/span&gt;=the collection on frames held within the frameset &lt;br&gt;&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;right&lt;/span&gt;&quot;=the id of the second frame &lt;br&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;document&lt;/span&gt;=what’s in the second frame &lt;/blockquote&gt;
&lt;p&gt;If you wanted, the id “right” could be swapped for the frame number, this is zero based so the second frame will be number 1, as in the example below.&lt;/p&gt;&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 591px; padding-right: 5px; height: 52px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;$(&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;p&lt;/span&gt;&quot;, &lt;span style=&quot;color: #0000ff&quot;&gt;window&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;parent&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;frames&lt;/span&gt;[1].&lt;span style=&quot;color: #0000ff&quot;&gt;document&lt;/span&gt;).text(&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;something else&lt;/span&gt;&quot;);&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;To make the other frame navigate to a different page we use a similar technique.&lt;/p&gt;&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 588px; padding-right: 5px; height: 52px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;$(&lt;span style=&quot;color: #0000ff&quot;&gt;window&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;parent&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;frames&lt;/span&gt;[&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;right&lt;/span&gt;&quot;].&lt;span style=&quot;color: #0000ff&quot;&gt;document&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;location&lt;/span&gt;)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;            .attr(&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;href&lt;/span&gt;&quot;,&quot;&lt;span style=&quot;color: #8b0000&quot;&gt;http://iainhoult.blogspot.com&lt;/span&gt;&quot;);&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;Or we can revert to using straight JavaScript, which is actually slightly shorter.&lt;/p&gt;&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 590px; padding-right: 5px; height: 52px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&#39;Courier New&#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;window&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;parent&lt;/span&gt;.right.&lt;span style=&quot;color: #0000ff&quot;&gt;document&lt;/span&gt;.&lt;span style=&quot;color: #0000ff&quot;&gt;location&lt;/span&gt;.href = &quot;&lt;span style=&quot;color: #8b0000&quot;&gt;http://iainhoult.blogspot.com&lt;/span&gt;&quot;;&lt;/pre&gt;&lt;/pre&gt;  </description><link>http://iainhoult.blogspot.com/2011/01/using-jquery-with-frames.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>12</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-5221575906339138112</guid><pubDate>Fri, 26 Nov 2010 16:53:00 +0000</pubDate><atom:updated>2010-11-27T15:30:14.996+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Data Access</category><category domain="http://www.blogger.com/atom/ns#">Deadlocks</category><category domain="http://www.blogger.com/atom/ns#">Error Handling</category><category domain="http://www.blogger.com/atom/ns#">SQL Server</category><title>Deadlock Handling</title><description>&lt;p&gt;I was rewatching a &lt;a href=&quot;http://www.msteched.com/2010/NorthAmerica/ARC308&quot; target=&quot;_blank&quot;&gt;presentation&lt;/a&gt; given by &lt;a href=&quot;http://www.udidahan.com&quot; target=&quot;_blank&quot;&gt;Udi Dahan&lt;/a&gt; at TechEd 2010 earlier this year, and I was reminded by his questioning of the audience about who was correctly handling their deadlocks, that really I wasn’t.&lt;/p&gt;  &lt;p&gt;Before I get started on what I did about deadlocks, let’s take a quick refresher on the problem:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;A deadlock is a stalemate situation, the simplest example goes like this; process one is holding resource A while needing resource B, at the same time process two is holding resource B while needing resource A. Each process is blocking the other so neither process can progress, at this point the database locking manager breaks the stalemate by killing off one process allowing the other to continue.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I am not sure how the locking manager decides who should be the victim of the deadlock, I am sure people much smarter than I am know, to me it seems to be tossing a coin in the air. There are ways to try and skew the outcome of this decision, namely setting the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms186736.aspx&quot; target=&quot;_blank&quot;&gt;deadlock_priority&lt;/a&gt; of a session. Using this setting allows you to try and emphasise important and non-important tasks, by letting you configure a deadlock priority value between -10 (please kill me) and 10 (don’t touch me), with 0 being the norm.&lt;/p&gt;  &lt;p&gt;Getting back to handling a deadlock in code, or my lack of, the point is that I was treating a deadlock like any other error, logging it and stepping back to a safe distance. But that is missing the point, it’s all in the error message:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;“Transaction (Process ID %d) was deadlocked on %.*ls resources with another process and has been chosen as the deadlock victim. Rerun the transaction.”&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Specifically it is the part of the message that says “Rerun the transaction”, because this is not really a failure message it is more of an instruction, to just wait until it is clear to progress.&lt;/p&gt;  &lt;p&gt;So that is what I implemented, it couldn’t be simpler, if the code gets a deadlock wait for a bit and then try again.&lt;/p&gt;  &lt;p&gt;As an example, I started out with something like this basic call to the database returning a DataTable:&lt;/p&gt;  &lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 561px; padding-right: 5px; height: 177px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; DataTable ReturnDataTable()
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;{
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;using&lt;/span&gt; (var dt = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; DataTable())
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          dt.Load(ActiveCommand.ExecuteReader());
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; dt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     }   
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;}
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;(Any errors that occur, including deadlocks, will bubble up and be taken care of at a higher level).&lt;/p&gt;

&lt;p&gt;To modify this function to handle deadlocks just needs us to catch any SqlExceptions and determine if they are deadlocks, if they are pause and try again:&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 562px; padding-right: 5px; height: 429px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; DataTable ReturnDataTable()
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;{
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;using&lt;/span&gt; (var dt = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; DataTable())
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;try&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               dt.Load(ActiveCommand.ExecuteReader());
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;catch&lt;/span&gt; (SqlException ex)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (ex.Number == 1205)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;                    System.Threading.Thread.Sleep(2000);
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;                    dt.Load(ActiveCommand.ExecuteReader());
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;                    &lt;span style=&quot;color: #0000ff&quot;&gt;throw&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;                 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; dt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;}
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Note that we are specifically checking for a SqlException with an error number of 1205 to determine if it is a deadlock (if you look at the messages within SQL Server you will see it is for the deadlock error mentioned above). &lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 564px; padding-right: 5px; height: 52px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #00008b&quot;&gt;select&lt;/span&gt; * from sys.messages where message_id=1205 &lt;span style=&quot;color: #0000ff&quot;&gt;and&lt;/span&gt; language_id=1033&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The length of time to wait may depend on what sort of process is likely to be blocking you, waiting 5ms might well be long enough. It would probably be useful to insert some level of randomness to the time paused, or to repeat the call several times within a short period.&lt;/p&gt;

&lt;p&gt;The above C# function is only an intermediate step, it has two problems; firstly the logic used to call the database is repeated, and secondly the deadlock logic would need to be repeated in every method.&lt;/p&gt;

&lt;p&gt;The solution is to create a deadlock handler function, to sit between the calling method and the method that calls the database:&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 560px; padding-right: 5px; height: 407px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;private&lt;/span&gt; T DeadlockHandler&amp;lt;T&amp;gt;(Func&amp;lt;T&amp;gt; innerFunction) 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;{
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     T result;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;try&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;      {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          result = innerFunction.Invoke();
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;catch&lt;/span&gt; (SqlException ex)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (ex.Number == 1205)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;           {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               System.Threading.Thread.Sleep(2000);
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               result = innerFunction.Invoke();
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;               &lt;span style=&quot;color: #0000ff&quot;&gt;throw&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; result;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;} 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Implementing the deadlock handler function as a generic function that takes in a Func&amp;lt;T&amp;gt;, keeps the code &lt;a href=&quot;http://en.wikipedia.org/wiki/Don&#39;t_repeat_yourself&quot; target=&quot;_blank&quot;&gt;DRY&lt;/a&gt;, the database logic isn’t repeated and neither is the deadlock logic.&lt;/p&gt;

&lt;p&gt;To use the deadlock handler with our example would need, a calling function: &lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 556px; padding-right: 5px; height: 93px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; DataTable ReturnDataTable()
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;{
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; DeadlockHandler&amp;lt;DataTable&amp;gt;(InnerReturnDataTable);
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;} 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And a function to communicate with the database (the original function):&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 560px; padding-right: 5px; height: 174px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;private&lt;/span&gt; DataTable InnerReturnDataTable()
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;{
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     &lt;span style=&quot;color: #0000ff&quot;&gt;using&lt;/span&gt; (var dt = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; DataTable())
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          dt.Load(ActiveCommand.ExecuteReader());
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;          &lt;span style=&quot;color: #0000ff&quot;&gt;return&lt;/span&gt; dt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;     }
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;}
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And that’s it, deadlock handling is not bad at all.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2010/11/deadlock-handling.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-9085756627027875752</guid><pubDate>Fri, 15 Oct 2010 15:43:00 +0000</pubDate><atom:updated>2010-10-15T16:43:05.640+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Error Handling</category><category domain="http://www.blogger.com/atom/ns#">UI</category><title>Errors, what to tell the user</title><description>&lt;p&gt;As much as we would like to believe our code is error free, that we never make mistakes and that unit tests make us bullet proof, there will always be bugs. It is a fact of life, it doesn’t matter if you are writing code on your own or for a massive corporation like Microsoft.&lt;/p&gt;  &lt;p&gt;Obviously you don’t want to have any bugs and you should do whatever you can to try and stop them creeping in, but you can’t control every circumstance or predict every situation.&lt;/p&gt;  &lt;p&gt;So my question is what do you do about it when you get an error? What should you be telling the user? How much technical information should you give?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;(Warning contains content that some may find offensive)&lt;/p&gt;  &lt;p&gt;&lt;object width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube-nocookie.com/v/Id_kGL3M5Cg?fs=1&amp;amp;hl=en_US&amp;amp;rel=0&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube-nocookie.com/v/Id_kGL3M5Cg?fs=1&amp;amp;hl=en_US&amp;amp;rel=0&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h4&gt;How much detail?&lt;/h4&gt;  &lt;p&gt;Ok, let’s compare what I consider to be the two different ends of the spectrum:&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Full technical details&lt;/h3&gt;  &lt;p&gt;I have used websites that have crashed and given me technical details. Is it any use to me at all to know there is a problem with the website’s database, or to get a stack trace? As the user of the website with no power to fix it, I would say no. The best thing I could do is take down all the details and pass them along to the website owner.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;No details &lt;/h3&gt;  &lt;p&gt;On the Apple iPhone if an application has a problem, it just gets closed by the operating system, and that’s it it’s just gone no message no anything. When this happen to me I think “oh the app’s died” and I reloaded it. Any detailed message would have been a waste, again all I could do with it is pass it on to the author of the app.&lt;/p&gt;  &lt;p&gt;To not display any error message to the user at all though, the idea that “there’s nothing they can do about it so why tell them anything”, I feel is a bit disrespectful to the user. I’m jumping ahead a little here, but wouldn’t a message like “App has encountered an error” with a button for &lt;em&gt;Close&lt;/em&gt; and another for &lt;em&gt;Reload&lt;/em&gt; perhaps be a nicer experience? Perhaps that is just a question of perception, “I have never had an error on my iPhone, sure apps sometimes close by themselves but it not like my PC where I get error messages all the time”.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Somewhere in the middle&lt;/h3&gt;  &lt;p&gt;A message dialog that initially appears with a user friendly error message and then, should the user wish they can expanded the technical details, is something I see on the PC a lot.&lt;/p&gt;  &lt;p&gt;So we start with a user friendly message, which is good as it’s user friendly, which is what we are aiming for. As for the technical detail, is there anything we can do with it? Well that opens up a whole new area of discussion.&lt;/p&gt;  &lt;p&gt;In the first two examples the user had no power over the environment they were using (website &amp;amp; iPhone), but this message is the sort that you might see on a PC, where there is at least the possibility that they can.&lt;/p&gt;  &lt;p&gt;Let’s take this as an example error; the user is trying to save what they are working on and they get the user friendly message “Can’t save document”, with a technical message “File ‘accounts.xls’ locked by another user”. It isn’t in user friendly speak anymore (what does “locked” mean), but if you have been around PCs for a while and you have a level of confidence with them, then you can read this message as “the file I’m working on is being messed around with by someone else in the office”, then all that needs to be done is find out who it is.&lt;/p&gt;  &lt;p&gt;So that was admittedly a very simple error to deal with and still lots of people that just use computers in their job, would be stuck by it. Most technical errors are going to be way more technical, which would be useful for any IT people trying to help the user, but not really for the users themselves.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;The developer’s point of view&lt;/h4&gt;  &lt;p&gt;Let’s change direction now and think about this from the developer’s point of view; there are two types of error, expected and unexpected.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Expected errors&lt;/h3&gt;  &lt;p&gt;The simple example above is an expected error, the document was locked by another user the developer knew it was likely to happen and coded for it.&lt;/p&gt;  &lt;h3&gt;&amp;#160;&lt;/h3&gt;  &lt;h3&gt;Unexpected errors&lt;/h3&gt;  &lt;p&gt;Then there is the unexpected error, which is the one developers should really care about (e.g. an OutOfMemoryException thrown deep within the application).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h3&gt;What to do with an error&lt;/h3&gt;  &lt;p&gt;What the developer wants is as many technical details as possible to be able to narrow down and squish the bug. What we have to be careful of is thinking we should show that information to the user, during development it might be nice to see it, but once it gets to the users it just turns into techo mumbo jumbo. In fact showing too much information could be disclosing details that make the application less secure.&lt;/p&gt;  &lt;p&gt;What the developer should be doing is logging the details and getting them back. For a website that’s easy as the logging is local, other applications might need to have a customer error reporting system. There are standard error handling system that can be tied in, such as &lt;a href=&quot;http://code.google.com/p/elmah/&quot; target=&quot;_blank&quot;&gt;ELMAH&lt;/a&gt;. Microsoft’s applications tie into their &lt;a href=&quot;http://www.microsoft.com/whdc/winlogo/maintain/StartWER.mspx&quot; target=&quot;_blank&quot;&gt;Windows error reporting&lt;/a&gt; system, which you as a developer can also use.&lt;/p&gt;  &lt;p&gt;And for the user the developer should be displaying the user friendly message, there’s no technical information that can help the user.&lt;/p&gt;  &lt;h4&gt;&amp;#160;&lt;/h4&gt;  &lt;h4&gt;In conclusion&lt;/h4&gt;  &lt;p&gt;Going back to the error message spectrum I think that less is more helpful, in fact I think that this error message I received when using Google Reader was just the right level, &amp;quot;Oops...an error occurred. Please try again in a few seconds&amp;quot;.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2010/10/errors-what-to-tell-user.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-4013505806232656801</guid><pubDate>Sun, 19 Sep 2010 19:01:00 +0000</pubDate><atom:updated>2010-11-27T15:22:53.264+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Design</category><title>Steal This Presentation</title><description>&lt;p&gt;Just like in the title, I’ve stolen this presentation from my old friend &lt;a href=&quot;http://www.robustsoftware.co.uk/&quot; target=&quot;_blank&quot;&gt;Garry’s blog&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;This is a really good presentation produced by Jesse Desjardins, demonstrating some excellent design tips.&amp;#160; Some of the magazine layouts aren’t quite to my taste, but I just wish I had half of Jesse’s design skills.&lt;/p&gt; &lt;object id=&quot;__sse5038209&quot; width=&quot;425&quot; height=&quot;355&quot;&gt; &lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=stealthispresentation-final-100823082633-phpapp02&amp;amp;stripped_title=steal-this-presentation-5038209&amp;amp;userName=GlobalGossip&quot; /&gt; &lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot; /&gt; &lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot; /&gt; &lt;embed name=&quot;__sse5038209&quot; src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=stealthispresentation-final-100823082633-phpapp02&amp;amp;stripped_title=steal-this-presentation-5038209&amp;amp;userName=GlobalGossip&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;355&quot;&gt; &lt;/embed&gt; &lt;/object&gt;  </description><link>http://iainhoult.blogspot.com/2010/09/steal-this-presentation.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-1337401910548049228</guid><pubDate>Tue, 27 Jul 2010 13:15:00 +0000</pubDate><atom:updated>2010-07-27T14:15:13.535+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AJAX</category><category domain="http://www.blogger.com/atom/ns#">ASP.Net</category><category domain="http://www.blogger.com/atom/ns#">Asynchronous</category><category domain="http://www.blogger.com/atom/ns#">jQuery</category><title>Using jQuery To Asynchronously Load Page Elements</title><description>&lt;p&gt;I like jQuery, but every time I get starting using it I unfortunately seem to get pulled onto a different project. Recently I was working on a little ASP.Net pet project something that I couldn’t get pulled off just as it’s getting interesting, as part of the coding I wanted to find out how to asynchronously load page elements.&lt;/p&gt;  &lt;p&gt;I wanted to do it using jQuery and I assumed it would be pretty straight forward (it’s even easier than I thought), but I couldn’t find anything that matched exactly what I wanted to do. Searching on &lt;a href=&quot;http://stackoverflow.com/questions/3093271/loading-a-page-with-ajax-for-beginners/3093290#3093290&quot; target=&quot;_blank&quot;&gt;StackOverflow&lt;/a&gt; I found a link to a &lt;a href=&quot;http://articles.sitepoint.com/article/ajax-jquery&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;tutorial&lt;/a&gt; with various jQuery exercises including asynchronously loading PHP pages.&lt;/p&gt;  &lt;p&gt;The PHP example was fairly close, and enough for me to work out how to use jQuery to asynchronously load page elements in ASP.Net.&lt;/p&gt;  &lt;p&gt;The following code is really a very simple example so that I don’t forget how to do it again. It is not meant to be a guide to learning jQuery from scratch. The example will load up a webpage and then asynchronously load up the contents of a drop-down list and display it on the webpage.&lt;/p&gt;  &lt;p&gt;To start with we are going to look at the webpage that will initially be loaded up:&lt;/p&gt;  &lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 588px; padding-right: 5px; height: 70px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  1:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;control&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  2:         &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;img&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;progress&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;ajax-loader.gif&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;alt&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;Loading...&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  3:         &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;select&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;loaded&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;style&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;display:none&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;select&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  4:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This is all that the body of the HTML contains; an image that displays an animated GIF as a progress indicator (something to show the user that a part of the screen is still loading and hasn’t frozen up). And a drop-down list which initially has no items listed and is not being displayed. These two tags are wrapped up in a DIV to make things tidy.&lt;/p&gt;

&lt;p&gt;The magic happens in the jQuery:&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 550px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  1:     &amp;lt;script type=&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;text/JavaScript&lt;/span&gt;&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  2:         $(&lt;span style=&quot;color: #0000ff&quot;&gt;document&lt;/span&gt;).ready(&lt;span style=&quot;color: #0000ff&quot;&gt;function&lt;/span&gt;() {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  3:             $(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;#control select&lt;/span&gt;&amp;quot;).load(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;DataGrabber.aspx&lt;/span&gt;&amp;quot;, &lt;span style=&quot;color: #0000ff&quot;&gt;function&lt;/span&gt;() {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  4:                 $(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;#progress&lt;/span&gt;&amp;quot;).hide();
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  5:                 $(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;#loaded&lt;/span&gt;&amp;quot;).show();
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  6:             });
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  7:         }); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  8:     &amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Once the HTML document has &lt;a href=&quot;http://api.jquery.com/ready/&quot; target=&quot;_blank&quot;&gt;finished loading&lt;/a&gt; (line 2) we use the jQuery &lt;a href=&quot;http://api.jquery.com/load/&quot; target=&quot;_blank&quot;&gt;.load()&lt;/a&gt; command to request the data from the server for our drop-down list element (line 3), this is retrieved from &amp;quot;DataGrabber.aspx&amp;quot;. After the data has been received another function is called, that will hide the progress indicator and display (now fully loaded) the drop-down list (lines 4 &amp;amp; 5).&lt;/p&gt;

&lt;p&gt;The complete listing for the webpage looks like this:&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 580px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  1: &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  2: &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  3:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;Asynchronous jQuery&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  4:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;text/JavaScript&amp;quot;&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  5:         &lt;span style=&quot;color: #ff0000&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  6:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  7: 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  8:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;type&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;text/JavaScript&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  9:         $(document).ready(function() {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 10:             $(&amp;quot;#control select&amp;quot;).load(&amp;quot;DataGrabber.aspx&amp;quot;, function() {
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 11:                 $(&amp;quot;#progress&amp;quot;).hide();
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 12:                 $(&amp;quot;#loaded&amp;quot;).show();
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 13:             });
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 14:         }); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 15:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 16: &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 17: 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 18: &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 19:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;control&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 20:         &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;img&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;progress&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;src&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;ajax-loader.gif&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;alt&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;Loading...&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;/&amp;gt;&lt;/span&gt; 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 21:         &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;select&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;id&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;loaded&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #ff0000&quot;&gt;style&lt;/span&gt;=&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;quot;display:none&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;select&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 22:     &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 23: &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 24: &lt;span style=&quot;color: #0000ff&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #800000&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The webpage is the first half of the equation, the second is getting the data.&amp;#160; This is the entire code for the &amp;quot;DataGrabber.aspx&amp;quot; page:&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 550px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  1: &amp;lt;script language=&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;VB&lt;/span&gt;&amp;quot; runat=&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;Server&lt;/span&gt;&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  2:     &lt;span style=&quot;color: #0000ff&quot;&gt;Public&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;Sub&lt;/span&gt; Main()
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  3:         Response.CacheControl = &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;No-Cache&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  4:         
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  5:         &lt;span style=&quot;color: #0000ff&quot;&gt;For&lt;/span&gt; counter = 1 &lt;span style=&quot;color: #0000ff&quot;&gt;To&lt;/span&gt; 10
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  6:             System.Threading.Thread.Sleep(400)
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  7:             
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  8:             Response.Write( _
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;  9:                 &lt;span style=&quot;color: #0000ff&quot;&gt;String&lt;/span&gt;.Format( _
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 10:                     &amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;&amp;lt;option&amp;gt;{0}&amp;lt;/option&amp;gt;&lt;/span&gt;&amp;quot;, _
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 11:                     counter.ToString))
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 12:         &lt;span style=&quot;color: #0000ff&quot;&gt;Next&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 13:     &lt;span style=&quot;color: #0000ff&quot;&gt;End&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;Sub&lt;/span&gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 14: &amp;lt;/script&amp;gt;
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 15: 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt; 16: &amp;lt;%  Main()%&amp;gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This is all server side code and for demonstration purposes is just outputting OPTION tags in a loop for a count of 1 to 10. Note that within the loop is a sleep of 400 milliseconds (line 6), this is to simulate a server side operation that takes a few seconds to execute, a few seconds that without this asynchronous call the user would have to be waiting for the page to load.&lt;/p&gt;

&lt;p&gt;As an additional point (taken straight from the &lt;a href=&quot;http://api.jquery.com/load/&quot; target=&quot;_blank&quot;&gt;API documentation&lt;/a&gt;) as something to watch out for:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Due to browser security restrictions, most &amp;quot;Ajax&amp;quot; requests are subject to the same &lt;a href=&quot;http://en.wikipedia.org/wiki/Same_origin_policy&quot; target=&quot;_blank&quot;&gt;origin policy&lt;/a&gt;; the request can not successfully retrieve data from a different domain, subdomain, or protocol.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;On a side note I am using a nice animated GIF file as my progress indicator, it has a customised image and colour scheme. I got it from the &lt;a href=&quot;http://www.ajaxload.info/&quot; target=&quot;_blank&quot;&gt;AjaxLoad website&lt;/a&gt; which will generate your custom GIF file for you in seconds.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2010/07/using-jquery-to-asynchronously-load.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-1639465015506730317</guid><pubDate>Fri, 16 Jul 2010 10:59:00 +0000</pubDate><atom:updated>2010-07-16T11:59:51.226+01:00</atom:updated><title>Junior Developer Wanted</title><description>&lt;p&gt;&lt;a href=&quot;http://www.openprojects.co.uk&quot;&gt;Open Projects&lt;/a&gt; are looking to hire a new Junior Developer, primarily to do .Net development.&lt;/p&gt;  &lt;p&gt;If you live in or around Nottingham, and you are interested in joining a team where you will learn a wide variety of skills doing a whole host of different jobs, why not send in your CV.&lt;/p&gt;  &lt;p&gt;Full details can be found &lt;a href=&quot;http://www.openprojects.co.uk/Careers.aspx&quot;&gt;here&lt;/a&gt;&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2010/07/junior-developer-wanted.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-3794751441881395260</guid><pubDate>Tue, 15 Dec 2009 17:02:00 +0000</pubDate><atom:updated>2010-11-27T15:24:56.640+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Blogging</category><title>Code snippets in your blog</title><description>&lt;p&gt;Before I start on this subject I had better lay out the facts; My blog is hosted on Google’s &lt;a href=&quot;http://www.blogger.com&quot; target=&quot;_blank&quot;&gt;Blogger&lt;/a&gt; and I use Microsoft’s &lt;a href=&quot;http://windowslivewriter.spaces.live.com/&quot; target=&quot;_blank&quot;&gt;Windows Live Writer&lt;/a&gt; to compose my posts, on the whole the two play nicely with each other.&lt;/p&gt;  &lt;p&gt;Previously when wanting to drop code snippets into a blog post I have used the source code formatter available on the &lt;a href=&quot;http://manoli.net/csharpformat/&quot; target=&quot;_blank&quot;&gt;manoli.net website&lt;/a&gt;.&amp;#160; It is quite user friendly, you go to the website paste in your code and hit the “format code” button.&amp;#160; The website will then give you the html that you will need to implant into your post.&amp;#160; The first time you use it, you will need to setup the stylesheet information it needs in order for the code snippet to be correctly formatted.&lt;/p&gt;  &lt;p&gt;The result is a nice looking code snippet that looks like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;pages.Add( 
    &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Page   
    { 
         Address = browser.Url.AbsoluteUri, 
         FileName = browser.Url.AbsolutePath, 
         Text = browser.DocumentText 
    } 
);&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Although I had previously setup the stylesheet information, when I came to writing my &lt;a href=&quot;http://iainhoult.blogspot.com/2009/12/its-free-website-but-its-only-static.html&quot; target=&quot;_blank&quot;&gt;last post&lt;/a&gt;, I though to myself “there must be an easier way to do this”.&amp;#160; What I found was the &lt;a href=&quot;http://gallery.live.com/liveItemDetail.aspx?li=10d724ab-0d28-4c78-8310-a6e2cfdef891&quot; target=&quot;_blank&quot;&gt;Source Code Formatter plugin&lt;/a&gt; for Windows Live Writer.&lt;/p&gt;

&lt;p&gt;Once installed you paste your code into the plugin’s window and when you are happy with it, it just goes straight into you post, no need to cut and paste html.&lt;/p&gt;

&lt;p&gt;I think it looks a bit nicer too, being in a box and having alternating coloured lines (both are configurable options):&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 400px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;pages.Add( 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; Page   
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    { 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;         Address = browser.Url.AbsoluteUri, 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;         FileName = browser.Url.AbsolutePath, 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;         Text = browser.DocumentText 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #f4ffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    } 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;The nice benefit here too, is that there is no need to setup any stylesheet information before you begin.&lt;/p&gt;

&lt;p&gt;It simple and pretty, I’m going to be using this one for a while to come.&lt;/p&gt;

&lt;p&gt;A good guide to getting setup with the plugin can be found on &lt;a href=&quot;http://skotl.blogspot.com/2009/02/posting-code-snipped-on-blogspotcom.html&quot; target=&quot;_blank&quot;&gt;Skot’s blog&lt;/a&gt;, where he goes into detail about installing and using the plugin, with some nice screen shots to show what’s happening.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2009/12/code-snippets-in-your-blog.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-7766298448079134299</guid><pubDate>Fri, 11 Dec 2009 16:18:00 +0000</pubDate><atom:updated>2010-11-27T15:48:26.405+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ASP.Net</category><category domain="http://www.blogger.com/atom/ns#">C#</category><title>It’s a free website, but it’s only static content</title><description>&lt;p&gt;I’m not sure or not whether this is a well known fact, but those nice people at Microsoft have been giving away free domain names and &lt;a href=&quot;http://www.officelive.com/&quot;&gt;web space&lt;/a&gt; to anybody that wants it for some time now.     &lt;br /&gt;They have started charging for custom domain names, although you can still operate your website as a sub domain of OfficeLive.com. The rest of the basics are still free, with just a few &lt;a href=&quot;http://smallbusiness.officelive.com/en-GB/pricing&quot;&gt;added charges&lt;/a&gt; should you want extra bits bolted on.&lt;/p&gt;  &lt;p&gt;It is designed for &lt;a href=&quot;http://fairypie.co.uk/default.aspx&quot;&gt;small businesses&lt;/a&gt;, and the basic way of setting up a website is to use existing templates, and just tweak them to customise the look. Advanced users get the ability to do away with the templates and write their own website from scratch.&lt;/p&gt;  &lt;p&gt;The only major downside I’ve found when writing your own website, is the fact that it has to be static. That’s right, nothing is permitted to operate server-side, forget &lt;a href=&quot;http://www.asp.net/mvc/&quot;&gt;asp.net mvc&lt;/a&gt;, you are forced back to the 90’s. I guess it is some sort of security thing, but even so IMHO it is a tad on the harsh side.&lt;/p&gt;  &lt;p&gt;On the plus side there is a way of getting round this, well sort of. You still can’t do anything “clever” with your website, but you can make it dynamic in a scenario such as displaying information on pages that is pulled out of a database.&lt;/p&gt;  &lt;p&gt;Write your website to work dynamically then save the pages it generates and use those as your static content on your live website.&lt;/p&gt;  &lt;p&gt;Admittedly manually doing this stops being scalable at the point you decide you have enough content to justify making your website dynamic in the first place. So manually doing it is out before you begin, but coding something up to do it for you couldn’t be simpler.&lt;/p&gt;  &lt;p&gt;Use a WebBrowser control to read a page from your dynamic site&lt;/p&gt;  &lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 450px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;browser.Navigate(&lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; Uri(address));&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Store its key details&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 450px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;pages.Add( 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; Page   
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    { 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;         Address = browser.Url.AbsoluteUri, 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;         FileName = browser.Url.AbsolutePath, 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;         Text = browser.DocumentText 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    } 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Then read all of the links off of the page&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 450px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;browser.Document.Body.GetElementsByTagName(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;A&lt;/span&gt;&amp;quot;);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And store them, remembering to only store links that go to pages on your own website (unless you plan on mapping the entire web).&lt;/p&gt;

&lt;p&gt;Now you just have to navigate to the first link you have recorded and read that page, repeat until you have visited every link on your website. At this point you can save the pages you have been storing to files.&lt;/p&gt;

&lt;pre style=&quot;border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 520px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px&quot;&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;span style=&quot;color: #0000ff&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #0000ff&quot;&gt;void&lt;/span&gt; Save() 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;{ 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;string&lt;/span&gt; folder = @&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;f:\webfiles&lt;/span&gt;&amp;quot; + DateTime.Now.ToString(&amp;quot;&lt;span style=&quot;color: #8b0000&quot;&gt;yyyyMMdd&lt;/span&gt;&amp;quot;); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (!Directory.Exists(folder)) 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;        Directory.CreateDirectory(folder); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;string&lt;/span&gt; fullPath = Path.Combine(folder, FileName); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;if&lt;/span&gt; (File.Exists(fullPath)) 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;        File.Delete(fullPath); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    &lt;span style=&quot;color: #0000ff&quot;&gt;using&lt;/span&gt; (var sw = &lt;span style=&quot;color: #0000ff&quot;&gt;new&lt;/span&gt; StreamWriter(fullPath)) 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    { 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;        sw.Write(Text); 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;    } 
&lt;/pre&gt;&lt;pre style=&quot;background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px&quot;&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This process could be quickly extended to generate sitemaps to allow search engines to more easily map your site. &lt;/p&gt;

&lt;p&gt;On the other hand you could, for a small fee, get some web space where you can use PHP and MySql and write a really dynamic website.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2009/12/its-free-website-but-its-only-static.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-3237122169150425110</guid><pubDate>Wed, 24 Jun 2009 12:28:00 +0000</pubDate><atom:updated>2010-11-27T15:47:21.054+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.Net</category><category domain="http://www.blogger.com/atom/ns#">Java</category><title>Small World</title><description>&lt;p&gt;Isn’t it a small world, well that is the conclusion I’ve come to anyway, after having the chance to catch up with an old friend who I hadn’t talked to for a while.&lt;/p&gt;  &lt;p&gt;Both of us being software developers the conversion soon got round to discussing what sort of tool/technologies we were both working with, I’m in the .Net camp while my friend is in the Java camp. So your first thought might be that there is not much in common between what we do (or perhaps you wouldn’t, I don’t really keep an eye on what’s happening in the Java world), but as it turns out we are doing very similar things.&lt;/p&gt;  &lt;p&gt;He is working with Groovy and &lt;a href=&quot;http://grails.org/&quot; target=&quot;_blank&quot;&gt;Grails&lt;/a&gt;, which as he put it is essentially a blend of Java, Ruby/Rails, &lt;a href=&quot;http://www.springsource.org/&quot; target=&quot;_blank&quot;&gt;Spring&lt;/a&gt; and &lt;a href=&quot;https://www.hibernate.org/&quot; target=&quot;_blank&quot;&gt;Hibernate&lt;/a&gt;. Groovy being based on Java and leveraging lots of the ideas from dynamic languages. Grails sits on top of Groovy and provides an MVC framework, together with built-in support for database-abstraction/&lt;a href=&quot;http://en.wikipedia.org/wiki/Object-relational_mapping&quot; target=&quot;_blank&quot;&gt;ORM&lt;/a&gt; (Hibernate) and user-interfaces (Spring).&lt;/p&gt;  &lt;p&gt;The names are different but the concepts are all starting to sound familiar; Hibernate = &lt;a href=&quot;http://nhforge.org/Default.aspx&quot; target=&quot;_blank&quot;&gt;nHibernate&lt;/a&gt;, Spring (which I’ve got to admit to being a little fuzzy on, even though it is also available for .Net) provides an MVC framework = ASP.Net MVC Framework, and an &lt;a href=&quot;http://en.wikipedia.org/wiki/Inversion_of_control&quot; target=&quot;_blank&quot;&gt;IoC&lt;/a&gt; system = &lt;a href=&quot;http://structuremap.sourceforge.net&quot; target=&quot;_blank&quot;&gt;StructureMap&lt;/a&gt; (our IoC system of choice).&lt;/p&gt;  &lt;p&gt;As the conversation went on, the language became exactly the same; Iterations, Design patterns, Coding principles (like convention-over-configuration) and Continuous Integration, they’re using &lt;a href=&quot;http://cruisecontrol.sourceforge.net/&quot; target=&quot;_blank&quot;&gt;CruiseControl&lt;/a&gt; while we are using Team City (mainly because we like &lt;a href=&quot;http://www.jetbrains.com/&quot; target=&quot;_blank&quot;&gt;Jet Brains’&lt;/a&gt; ReSharper so much).&lt;/p&gt;  &lt;p&gt;We even talked about source control, which was the spookiest point, as not only were we both using svn, but we were both using &lt;a href=&quot;http://tortoisesvn.net/&quot; target=&quot;_blank&quot;&gt;TortoiseSVN&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Is it strange that we are doing the same sort of things? Probably not, as we are both trying to achieve the same goals (writing quality, reliable and maintainability software) and there is cross pollination of ideas and technology between the two camps, apparently much more than I realised.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2009/06/small-world.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-1158456619614327776</guid><pubDate>Thu, 04 Jun 2009 15:08:00 +0000</pubDate><atom:updated>2010-11-27T15:31:06.575+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SQL Server</category><title>SQL Server Tricks to Remember</title><description>&lt;p&gt;This post is really just somewhere to keep these SQL Server stored procedures so that I don’t forget them. They are a couple of useful system stored procedures that ship with SQL Server. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;sp_change_users_login&lt;/h5&gt;  &lt;p&gt;Used for mapping database users against SQL Server logins. &lt;/p&gt;  &lt;p&gt;To determine what users exist on the database that are not mapped to logins on SQL Server:    &lt;br /&gt;&lt;font color=&quot;#800000&quot; face=&quot;Courier New&quot;&gt;sp_change_users_login &#39;report&#39;&lt;/font&gt;     &lt;br /&gt;To map a database user to an existing SQL Server login:     &lt;br /&gt;&lt;font color=&quot;#800000&quot; face=&quot;Courier New&quot;&gt;sp_change_users_login &#39;auto_fix&#39;, &#39;&lt;em&gt;username&lt;/em&gt;&#39; &lt;/font&gt;    &lt;br /&gt;To map a database and create an SQL Server login at the same time:     &lt;br /&gt;&lt;font color=&quot;#800000&quot; face=&quot;Courier New&quot;&gt;sp_change_users_login &#39;auto_fix&#39;, &#39;&lt;em&gt;username&lt;/em&gt;&#39;, null, &#39;&lt;em&gt;password&lt;/em&gt;&#39; &lt;/font&gt;    &lt;br /&gt;(The null parameter is the SQL Server login) &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h5&gt;sp_MSforeachtable &lt;/h5&gt;  &lt;p&gt;Undocumented stored procedure used for executing the same command against every table in a database. &lt;/p&gt;  &lt;p&gt;To get the number of rows from each table in a database:    &lt;br /&gt;&lt;font color=&quot;#800000&quot; face=&quot;Courier New&quot;&gt;sp_MSforeachtable &amp;quot;select count(*) as &#39;?&#39; from ?&amp;quot; &lt;/font&gt;    &lt;br /&gt;(The ? character is used as a placeholder for the table name)     &lt;br /&gt;To get the number of rows for each table whose name starts with I:     &lt;br /&gt;&lt;font color=&quot;#800000&quot; face=&quot;Courier New&quot;&gt;sp_MSforeachtable      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @command1 = &amp;quot;select count(*) as &#39;?&#39; from ?&amp;quot;,       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; @whereand = &amp;quot;and o.name like &#39;i%&#39;&amp;quot; &lt;/font&gt;    &lt;br /&gt;(There can be 3 different commands executed against each table per run, specified as @command1, @command2 and @command3. @whereand allows the selection of specific tables.)     &lt;br /&gt;There is also the ability to run a command before and after all the tables are processed, @precommand and @postcommand respectively. &lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2009/06/sql-server-tricks-to-remember.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-3764270486854885470</guid><pubDate>Thu, 26 Mar 2009 17:48:00 +0000</pubDate><atom:updated>2010-11-27T15:45:51.833+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.Net</category><category domain="http://www.blogger.com/atom/ns#">C#</category><title>If you look, it might well be there</title><description>&lt;p&gt;When the .Net Framework first came out I can remember seeing several articles that said we, as developers, needed to learn the different namespaces within the framework. &lt;/p&gt;  &lt;p&gt;This was brought back to mind recently when I was reviewing a few pieces of code, and I realised that the authors of the code had been doing their own code rather than using the functions available to them in the framework. Specifically they where reinventing the System.IO namespace, the two functions in question were:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;System.IO.Path.Combine&lt;/strong&gt; – For concatenating a path with a filename to get a valid path/filename string.&lt;/p&gt;  &lt;p&gt;and&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;System.IO.Path.GetFileNameWithoutExtension&lt;/strong&gt; – As the name suggests for getting the name of the file minus its extension from a full path.&lt;/p&gt;  &lt;p&gt;I think we all know the main parts of the framework, all the bits that we use all the time, but I bet there&#39;s lots of really useful stuff in there that could be a real help if we just took a little time to explore what is available.&lt;/p&gt;  &lt;p&gt;I say “we” because I think I&#39;m going to take my own advise and have a look through some of the namespaces that I normally never use. Who knows, I might make life a little easier for myself.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2009/03/if-you-look-it-might-well-be-there.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-485583923286358900</guid><pubDate>Sat, 31 Jan 2009 11:15:00 +0000</pubDate><atom:updated>2010-11-27T15:44:35.972+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">C#</category><title>Build Your Own “Fluent Interface”</title><description>&lt;p&gt;As I was putting together a fluent interface recently I decided it might be a good topic to blog about, to try and show why they are a very useful way of doing things.&lt;/p&gt;  &lt;p&gt;A fluent interface is really just a nice way of passing information into an object though your code.&amp;#160; It’s really a very simple technique, so to give you an idea of how one works I will give you some comparisons against the one I put together.&lt;/p&gt;  &lt;p&gt;I was doing some black-box testing of an application that validated information held in a database, to help me with this task I created a helper object that would insert a record into my test database.&amp;#160; There were various fields associated with the record that I needed to be able to configure easily to create the correct data for each test scenario.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;There were three different ways that I could have set this up to work...&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Properties&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The test method is the one exercising the helper object shown below.&amp;#160; We create an instance of our helper, set its properties and then call the Create() function to do the database work.&lt;/p&gt;  &lt;p&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;/p&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Test1()
    {
        HelperProp helper = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperProp();

        helper.Validated = &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;
        helper.Downloaded = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
        helper.ComplexMode = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;

        &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; testRecord = helper.Create();
        &lt;span class=&quot;rem&quot;&gt;// Test code removed for clarity&lt;/span&gt;
    }&lt;/pre&gt;

&lt;p&gt;The helper exposes the various properties that are needed by the coder, and has a method to store the test record in the database.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; HelperProp
    {
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Validated { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Uploaded { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Downloaded { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; ComplexMode { get; set; }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Create()
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; DB.ExecuteScalar(
                &lt;span class=&quot;str&quot;&gt;&amp;quot;INSERT into TestTable ({0},{1},{2},{3})&amp;quot;&lt;/span&gt;, 
                Validated, Uploaded, Downloaded, ComplexMode);
        }
    }&lt;/pre&gt;

&lt;p&gt;The downside with properties is that setting them, can get a tad verbose.&amp;#160; It might not look that much here, but I have cut down the number of options in the example considerable, plus this is just one of the types of record I needed to be able to control, and this is just the one test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constructors &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This test method does the same thing as the previous one, but this time the options are all set via the helper’s constructor.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Test2()
    {
        HelperCtor helper = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperCtor(&lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;);

        &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; testRecord = helper.Create();
        &lt;span class=&quot;rem&quot;&gt;// Test code removed for clarity&lt;/span&gt;
    }&lt;/pre&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The helper now just takes in those options into it’s constructor.&lt;/p&gt;

&lt;p&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; HelperCtor
    {
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _validated;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _uploaded;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _downloaded;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _complexMode;

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperCtor(
            &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; validated, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; uploaded, 
            &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; downloaded, &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; complexMode)
        {
            _validated = validated;
            _uploaded = uploaded;
            _downloaded = downloaded;
            _complexMode = complexMode;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Create()
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; DB.ExecuteScalar(
                &lt;span class=&quot;str&quot;&gt;&amp;quot;INSERT into TestTable ({0},{1},{2},{3})&amp;quot;&lt;/span&gt;,
                _validated, _uploaded, _downloaded, _complexMode);
        }
    }&lt;/pre&gt;

&lt;p&gt;With this method we have moved the verbose code out of the tests and into the helper object.&lt;/p&gt;

&lt;p&gt;We really only want to set a couple of options but with this constructor all of them need setting, and answer would be to have multiple constructor of different formats, as we are dealing with boolean values this could become a pain if we only want to set certain combinations.&lt;/p&gt;

&lt;p&gt;There is another downside with using constructors for configuring our helper object and that is readability.&amp;#160; With the helper we are setting a lot of boolean values, so the call to the constructor, as can been seen in the test, is only a collection of true/false values not exactly the most intuitive code to read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fluent Interface &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The test method is now very concise, there’s really only one line for the setup of the helper, plus it is very readable.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Test3()
    {
        HelperFI helper = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperFI();

        &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; testRecord = helper.Downloaded().ComplexMode().Create();
        &lt;span class=&quot;rem&quot;&gt;// Test code removed for clarity&lt;/span&gt;
    }&lt;/pre&gt;

&lt;p&gt;The magic is in the helper’s functions, they do two simple things; store the setting and return a helper (in fact the same one).&amp;#160; That’s it, because each function returns the helper it is possible to chain the functions, making a fluent interface.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; HelperFI
    {
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _validated;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _uploaded;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _downloaded;
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; _complexMode;

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperFI Validated()
        {
            _validated = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperFI Uploaded()
        {
            _uploaded = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperFI Downloaded()
        {
            _downloaded = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperFI ComplexMode()
        {
            _complexMode = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
        }


        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Create()
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; DB.ExecuteScalar(
                &lt;span class=&quot;str&quot;&gt;&amp;quot;INSERT into TestTable ({0},{1},{2},{3})&amp;quot;&lt;/span&gt;,
                _validated, _uploaded, _downloaded, _complexMode);
        }
    }&lt;/pre&gt;

&lt;p&gt;With the fluent interface version of the helper, there is more code, but only about the same as if we had used the longhand version of properties (in fact we could have used properties, which would have got rid of the brackets in the test method). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fluent Interface - Extended&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes it is not logical to give the coder all the options at once, so you can achieve a sort of hierarchy by returning different classes which reduce/allow different options. &lt;/p&gt;

&lt;p&gt;Lets say that we wanted to restrict the options from the example, so that the coder must first choose uploaded/downloaded, then validated/ComplexMode, and only after that be able to call the Create() function.&lt;/p&gt;

&lt;p&gt;The test method would be virtually identical to the previous one.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Test4()
    {
        HelperHierarchy helper = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperHierarchy();

        &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; testRecord = helper.Downloaded().ComplexMode().Create();
        &lt;span class=&quot;rem&quot;&gt;// Test code removed for clarity&lt;/span&gt;
    }&lt;/pre&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;The helper I have split into four classes; the first one is just a dumb &lt;a href=&quot;http://martinfowler.com/eaaCatalog/dataTransferObject.html&quot; target=&quot;_blank&quot;&gt;DTO&lt;/a&gt; to hold the option settings.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Values
    {
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Uploaded { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Downloaded { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; Validated { get; set; }
        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; ComplexMode { get; set; }
    }&lt;/pre&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;The second is the top level class that the coder will use.&amp;#160; It only has the options of Uploaded and Download, both of these functions return the next level class passing into it the DTO.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; HelperHierarchy
    {
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; Values _values { get; set; }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperSubHierarchy Uploaded()
        {
            _values.Uploaded = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperSubHierarchy(_values);
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperSubHierarchy Downloaded()
        {
            _values.Downloaded = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperSubHierarchy(_values);
        }
    }&lt;/pre&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;The third level is quite similar to the second, this time only allowing the Validated and ComplexMode options to be available, both returning the final level again passing along the DTO with all the settings.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; HelperSubHierarchy
    {
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; Values _values { get; set; }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperSubHierarchy(Values values)
        {
            _values = values;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperCreator Validated()
        {
            _values.Validated = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperCreator(_values);
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperCreator ComplexMode()
        {
            _values.ComplexMode = &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; HelperCreator(_values);
        }
    }&lt;/pre&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;The final level has the Create() function, that just pulls the settings out of the DTO to do its database work.&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; HelperCreator
    {
        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; Values _values { get; set; }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; HelperCreator(Values values)
        {
            _values = values;
        }

        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Create()
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; DB.ExecuteScalar(
                &lt;span class=&quot;str&quot;&gt;&amp;quot;INSERT into TestTable ({0},{1},{2},{3})&amp;quot;&lt;/span&gt;,
                _values.Validated, _values.Uploaded, _values.Downloaded, _values.ComplexMode);
        }
    }&lt;/pre&gt;

&lt;p&gt;Just as a final note of interest there is another tricks that you can do with fluent interfaces, by using &lt;a href=&quot;http://iainhoult.blogspot.com/2008/03/extension-method-what-why-where-when.html&quot; target=&quot;_blank&quot;&gt;Extension Methods&lt;/a&gt; you can give an existing object a fluent interface. &lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2009/01/build-your-own-fluent-interface.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-4202770244889603750</guid><pubDate>Fri, 04 Apr 2008 08:11:00 +0000</pubDate><atom:updated>2010-11-27T15:39:34.046+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Best Practice</category><category domain="http://www.blogger.com/atom/ns#">C#</category><title>Self Documenting Code 101</title><description>&lt;p&gt;Something that I am very keen on is &amp;quot;Self documenting code&amp;quot; by which I mean code written in such a way that makes it easy to read and maintain.&lt;/p&gt;  &lt;p&gt;Ok, I know what you are thinking &amp;quot;my code is easy to read&amp;quot;, well good I hope it is, this post isn&#39;t aimed at the developer with years of experience, but saying that how many times have you had to work on a piece of code that takes you longer to decipher than to do what you need with?&amp;#160; How often after you got mad at that code did you realise that you were the author?&lt;/p&gt;  &lt;p&gt;The more readable your code, the more maintainable your code, the less stress for you as a developer.&lt;/p&gt;  &lt;p&gt;Let&#39;s start with a very small example method:&lt;/p&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Calc(Order[] orders)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; result = 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (i = 0; i &amp;lt; 7; i++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (orders[i].Sales &amp;gt; 10.1f)&lt;br /&gt;                {&lt;br /&gt;                    result++;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; result;&lt;br /&gt;        }&lt;/pre&gt;

&lt;p&gt;So what does it do? &lt;/p&gt;

&lt;p&gt;It takes some orders and loops round them seven times adding up where the sales are greater than 10.1 and returning the result, anything else would really be guessing. Now how did we work that out, well the method parameter is called &amp;quot;orders&amp;quot; of type &amp;quot;Order&amp;quot; so it&#39;s something to do with orders and it uses a property called &amp;quot;Sales&amp;quot; and oh yes there&#39;s a number &amp;quot;7&amp;quot; in the loop.&amp;#160; If the parameter was called &amp;quot;os&amp;quot; of type &amp;quot;O&amp;quot; we wouldn&#39;t have a clue.&lt;/p&gt;

&lt;p&gt;So what should we do to make it more readable?&amp;#160; Add some comments perhaps:&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Calc(Order[] orders)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; result = 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// loop round seven times&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (i = 0; i &amp;lt; 7; i++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;rem&quot;&gt;// if the sales value is greater than 10.1 increment the result&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (orders[i].Sales &amp;gt; 10.1f)&lt;br /&gt;                {&lt;br /&gt;                    result++;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; result;&lt;br /&gt;        }&lt;/pre&gt;

&lt;p&gt;Comments are good, they are probably the most obvious way of documenting your code, but do these comments actually help?&amp;#160; &amp;quot;loop round seven times&amp;quot; as a comment for a loop that goes round seven times, we can all read what the code is doing but can we tell why it&#39;s doing it?&lt;/p&gt;

&lt;p&gt;Lets take the comments back out and this time change that variable &amp;quot;i&amp;quot; to something better:&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Calc(Order[] orders)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; day;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; result = 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (day = 0; day &amp;lt; 7; day++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (orders[day].Sales &amp;gt; 10.1f)&lt;br /&gt;                {&lt;br /&gt;                    result++;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; result;&lt;br /&gt;        }&lt;/pre&gt;

&lt;p&gt;Now that starts to make things clearer, the method is looking at different day&#39;s orders, one order for every day of the week.&amp;#160; IMHO giving that one variable a descriptive name has made the code much more readable than adding the comments did.&amp;#160; Repeat after me, &amp;quot;single letter variable names are evil&amp;quot;.&lt;/p&gt;

&lt;p&gt;The next step is to get rid of those &amp;quot;magic numbers&amp;quot;, that is the random numbers mixed up in the middle of the code:&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Calc(Order[] orders)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; day;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; result = 0;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; daysInWeek = 7;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;float&lt;/span&gt; salesTarget = 10.1f;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (day = 0; day &amp;lt; daysInWeek; day++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (orders[day].Sales &amp;gt; salesTarget)&lt;br /&gt;                {&lt;br /&gt;                    result++;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; result;&lt;br /&gt;        }&lt;/pre&gt;

&lt;p&gt;Oh, a sales target, that&#39;s what the &amp;quot;10.1&amp;quot; was all about, this method calculates how many days in a week somebody hits their sales targets!&amp;#160; Still no comments, but now we can tell exactly what this method is meant to be doing.&lt;/p&gt;

&lt;p&gt;If you look at the start of the loop, you will see that I have left the initial value of the &amp;quot;day&amp;quot; variable within the code, there isn&#39;t anything to gain in changing this unless it is likely to be modified.&amp;#160; You could make the same argument about the &amp;quot;daysInWeek&amp;quot;, but then there might only be 5 days in the working week.&lt;/p&gt;

&lt;p&gt;The last thing we will look at is the actual name of the method, and I&#39;m going to be a little cheeky here and refactor the method into two:&lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; SalesTargetHitDuringWeek(Order[] orders)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; day;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; result = 0;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; daysInWeek = 7;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (day = 0; day &amp;lt; daysInWeek; day++)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (IsAboveSalesTarget(orders[day]))&lt;br /&gt;                    result++;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; result;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;bool&lt;/span&gt; IsAboveSalesTarget(Order order)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;float&lt;/span&gt; salesTarget = 10.1f;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (order.Sales &amp;gt; salesTarget)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;        }&lt;/pre&gt;

&lt;p&gt;I have extracted the logic that handles checking if sales have hit their target and put it into its own method.&amp;#160; Now both methods have names that properly describe their purpose, the methods are small and only have the one responsibility described in the name.&amp;#160; The names that I chose are long enough to describe the methods without being verbose, and thanks to IntelliSense you don&#39;t need to wear your finger away when using them.&lt;/p&gt;

&lt;p&gt;Hopefully this quick example has illustrated some very simple techniques for making your code &amp;quot;self documenting&amp;quot;, and we didn&#39;t even have to write any comments.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2008/04/self-documenting-code-101.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-8335856959516462440</guid><pubDate>Thu, 03 Apr 2008 12:53:00 +0000</pubDate><atom:updated>2010-11-27T15:37:24.449+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Best Practice</category><title>Phrases to develop by</title><description>&lt;p&gt;Over time I have picked up various programming tips that I have taken to heart, some of these are well known and I am sure you can find countless article on them, others are ones that I have picked up where I have worked, all of these are commonsense.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Fail Fast&lt;/h4&gt;  &lt;p&gt;Failing fast may sound a little backwards, but when you are developing code it is a good thing to have errors show up and to show up fast.&amp;#160; The faster you know there is an error the faster you can fix it, and the more likely you are to catch it while developing your code, rather than after it has gone live.&lt;/p&gt;  &lt;p&gt;The main way to do this is not to allow every bit of code to have its own error handling.&amp;#160; &amp;quot;No error handling, that&#39;s crazy talk!&amp;quot;, no I am not talking about a complete absence on error handling, what I am suggesting is the error handling is left at responsible levels in your code structure, where you can see them easily and deal with them.&lt;/p&gt;  &lt;p&gt;Having low level methods handling their own errors can also leave you applications in an unknown state, which would make the security guys very excitable.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Keep it simple stupid (KISS)&lt;/h4&gt;  &lt;p&gt;That&#39;s not me being rude, blame the guy who thought up this phrase and needed a second S.&lt;/p&gt;  &lt;p&gt;This one is really easy; keep you code simple, don&#39;t write big complicated methods.&amp;#160; Do you like debugging big complicated method? No, so don&#39;t write them, write much smaller methods that are restricted to doing one thing (have one responsibility).&lt;/p&gt;  &lt;p&gt;If nothing else when you come to debugging a problem, that stack trace will point you to a method with only a few line of code in it, much easier than a method that is a few pages long.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;You ain&#39;t gonna need it (YAGNI)&lt;/h4&gt;  &lt;p&gt;Does our code need to be all things to all people?&amp;#160; No, it needs to do the task for which it is designed.&amp;#160; &lt;/p&gt;  &lt;p&gt;If you know that in six months there will be extra functionality needed in an area you are working on, should you include code to handle it?&amp;#160; You could, but in six months time that extra functionality might not be needed, even if it is then the specification will probably have changed leaving you needed to rework any code you have already added.&lt;/p&gt;  &lt;p&gt;If you know that something you are working on is likely to change, don&#39;t ignore it, treat it as a hint so you know not to put anything in place that would block it.&amp;#160; But don&#39;t spend your precious time trying to integrate it now.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;If you ignore it, it will come back and bite you on the bum&lt;/h4&gt;  &lt;p&gt;A phrase I was told to remember when I first started out as a junior developer, and one I thought would go well after YAGNI.&lt;/p&gt;  &lt;p&gt;This is not the opposite of YAGNI as it might first appear, in the example above you are not ignoring anything, you are just leaving it until a more appropriate time.&lt;/p&gt;  &lt;p&gt;This is that completely random, a billion to one scenario, that the user will never get.&amp;#160; You know the one, it&#39;s the one that is going to keep you debugging late into the night when it makes your app go funny and your customers get upset.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Write self documenting code&lt;/h4&gt;  &lt;p&gt;Not really a phrase, more a request I guess.&lt;/p&gt;  &lt;p&gt;You should be able to go to your code and read it, and what&#39;s more you should be able to go back to your code in six months and still be able to read it.&amp;#160; You should be able to go to your code and not need to spend half your time trying to workout what it is doing, before you can add your new feature or fix that bug.&lt;/p&gt;  &lt;p&gt;The whys and wherefores of this are fairly basic, but there are quite a few so I will leave them for their own post.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Don&#39;t Repeat Yourself (DRY)&lt;/h4&gt;  &lt;p&gt;A very good piece of advice, that is a basic tenant of good design.&lt;/p&gt;  &lt;p&gt;If you need to do the same sort of task in multiple places, don&#39;t rewrite that similar code, just do it once and have the calling code handle any differences.&lt;/p&gt;  &lt;p&gt;For example your code might need to access a database for various task, you could have lots of different methods take on the responsibility of creating command objects against connections and executing them to get your data.&amp;#160; The alternative is to create one method that takes on this responsibility, that the methods who need the data call passing in some SQL or stored procedure details.&amp;#160; (Hopefully you know exactly what I&#39;m talking about, if not Google &amp;quot;database gateway&amp;quot;).&lt;/p&gt;  &lt;p&gt;Another example could be where you have two objects that do similar tasks, the duplicated operations could be moved to a base class, that both your original classes inherit.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Assumptions are the mother of disaster&lt;/h4&gt;  &lt;p&gt;I first remember hearing this phrase when watching a film, it had nothing to do with computers but it is the sort of statement that can apply to anything.&lt;/p&gt;  &lt;p&gt;It is very simple, if you make an assumption and it is wrong then it is a bad thing, if that assumption is at the heart of what your developing then it is a very bad thing.&amp;#160; We all have to make assumptions, it is a balancing act, little assumptions are normally ok to sort out, it is the big ones you want to avoid.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I hope you found some of these phrases useful, I certainly have over the years.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2008/04/phrases-to-develop-by.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8081372847405402819.post-4966204025175083659</guid><pubDate>Tue, 18 Mar 2008 15:05:00 +0000</pubDate><atom:updated>2009-01-23T15:16:58.721+00:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.Net 3.5</category><title>Extension Method – What, why, where, when?</title><description>&lt;p&gt;Ever since .Net 3.5 and Visual Studio 2008 came out there has been lots about its new features, such as Linq and Lambda Expressions, but a nice little feature that seems to be getting overlooked is the ability to create Extension Methods.&lt;/p&gt;  &lt;h4&gt;What is an Extension Method?&lt;/h4&gt;  &lt;p&gt;Have you ever been frustrated that an object (closed off to you) doesn’t have a particular method, something that would seem the most logical little method for the object to have, but it just doesn’t, I have.&lt;/p&gt;  &lt;p&gt;Well now those nice folk at Microsoft have come up with a way for us to get that missing method, they have given us the ability to add methods to an object to extend it, the aptly name “Extension Methods”.&lt;/p&gt;  &lt;p&gt;For our example below, I could have gone really basic with just enough code to demonstrate the principle, but I like to give fuller examples. Ok, time for a little code...&lt;/p&gt;  &lt;p&gt;Here is a very simple email gateway class: &lt;/p&gt;  &lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; System.Net.Mail;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;namespace&lt;/span&gt; ExtensionMethods&lt;br /&gt;{&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EmailGateway&lt;br /&gt;    {&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; SmtpClient _smtpClient;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; MailMessage _mailMessage;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; EmailGateway()&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// Create mail server and email objects&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._smtpClient = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; SmtpClient(&lt;span class=&quot;str&quot;&gt;&amp;quot;mailserver&amp;quot;&lt;/span&gt;);&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; MailMessage();&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// Set fixed sender&#39;s address&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.From = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; MailAddress(&lt;span class=&quot;str&quot;&gt;&amp;quot;address@domain.com&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SendEmail(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; toAddress, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; subject, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; body)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// Configure email with passed parameters&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.To.Add(toAddress);&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.Subject = subject;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.Body = body;&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// Use mail server to send email&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._smtpClient.Send(_mailMessage);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

&lt;br /&gt;With the code to exercise it: 

&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; EmailSomeone()&lt;br /&gt;{ &lt;br /&gt;        EmailGateway emailGateway = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EmailGateway();&lt;br /&gt;        emailGateway.SendEmail(&lt;span class=&quot;str&quot;&gt;&amp;quot;someone@domain.com&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;test email&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;this is a test&amp;quot;&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;


&lt;p&gt;This code is fine, until you try to send an email to multiple people, for example: &lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;emailGateway.SendEmail(&lt;span class=&quot;str&quot;&gt;&amp;quot;someone@domain.com;other@domain.com&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;test email2&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;this is another test&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


&lt;p&gt;When we try this we get a FormatException because the MailMessage.To.Add() method is only able to handle one email address at a time. This is the point where I would like to call a nice AddRange() method, except unluckily for us there isn’t one.&lt;/p&gt;

&lt;p&gt;There is no silver bullet to get more that one address added to our email, somewhere we are going to have to write some code that takes a collection of addresses and added them to the email. The question is how can we make our code as elegant as possible?
  &lt;/p&gt;

&lt;p&gt;Behold the Extension Method: &lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; System.Linq;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; System.Net.Mail;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kwrd&quot;&gt;namespace&lt;/span&gt; ExtensionMethods&lt;br /&gt;{&lt;br /&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; MailAddressCollectionExtensions&lt;br /&gt;    {&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AddRange(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt; MailAddressCollection collection, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; toAddresses)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// Remove any existing addresses, so our range are the only ones&lt;/span&gt;&lt;br /&gt;            collection.Clear();&lt;br /&gt;&lt;br /&gt;            &lt;span class=&quot;rem&quot;&gt;// Parse the passed addresses, adding each one to the colection&lt;/span&gt;&lt;br /&gt;            toAddresses&lt;br /&gt;                .Split(&lt;span class=&quot;str&quot;&gt;&amp;quot;;&amp;quot;&lt;/span&gt;.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)&lt;br /&gt;                .ToList()&lt;br /&gt;                .ForEach(address =&amp;gt; collection.Add(address));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;



&lt;p&gt;The extension method is a simple static method with one special part, in the method signature the first parameter is the object we are extending, notice it is preceded by the &lt;strong&gt;this&lt;/strong&gt; keyword. This has to be the first parameter, any other parameters we define are the ones that will be pass in, so we are extending _mailMessage.To and passing in toAddresses.&lt;/p&gt;

&lt;p&gt;And to use it we simply need to change the &amp;quot;To&amp;quot; line in our email gateway code: &lt;/p&gt;

&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SendEmail(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; toAddresses, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; subject, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; body)&lt;br /&gt;{&lt;br /&gt;        &lt;span class=&quot;rem&quot;&gt;// Configure email with passed parameters&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.To.AddRange(toAddresses);&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.Subject = subject;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._mailMessage.Body = body;&lt;br /&gt;        &lt;span class=&quot;rem&quot;&gt;// Use mail server to send email&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._smtpClient.Send(_mailMessage);&lt;br /&gt;} &lt;/pre&gt;

&lt;br /&gt;


&lt;h4&gt;Why?&lt;/h4&gt;

&lt;p&gt;Extension methods were added to help Linq work with the existing System.Collections.IEnumerable and System.Collections.Generic.IEnumerable(T) types.

&lt;br /&gt;

To tell if a method is an Extension method or not is really simple, just look at the little icon that Intellisense gives you, if it’s got a little blue arrow on it pointing straight down then you’ve got yourself an Extension method.
  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://lh6.google.com/IainHoult/R9_aGfdV6CI/AAAAAAAAABU/fkxGJUazF7s/Intellisense%5B8%5D&quot;&gt;&lt;img style=&quot;border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px&quot; border=&quot;0&quot; alt=&quot;Intellisense&quot; src=&quot;http://lh4.google.com/IainHoult/R9_aG_dV6DI/AAAAAAAAABg/IfApjfBdb9A/Intellisense_thumb%5B6%5D&quot; width=&quot;523&quot; height=&quot;297&quot; /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;

&lt;br /&gt;

&lt;h4&gt;Where?&lt;/h4&gt;

&lt;p&gt;The example has the Extension method in its own class, you don’t need to do it that way, in fact I am always cautious about adding “utility” classes into projects, they have a tendency to start filling up with random code that should really be somewhere else. &lt;/p&gt;

&lt;br /&gt;

&lt;h4&gt;When?&lt;/h4&gt;

&lt;p&gt;The purpose and use of Extension methods are to extend closed objects, that really says it, they are not there for us to extend our own objects, but ones that we have no control over and wish we did.&lt;/p&gt;  </description><link>http://iainhoult.blogspot.com/2008/03/extension-method-what-why-where-when.html</link><author>noreply@blogger.com (Iain Hoult)</author><thr:total>0</thr:total></item></channel></rss>