<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Peter Ritchie's MVP Blog : .NET 2.0</title><link>http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx</link><description>Tags: .NET 2.0</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>DevTeach 2009 Vancouver</title><link>http://msmvps.com/blogs/peterritchie/archive/2009/03/26/devteach-2009-vancouver.aspx</link><pubDate>Thu, 26 Mar 2009 16:33:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1681658</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1681658</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2009/03/26/devteach-2009-vancouver.aspx#comments</comments><description>&lt;p&gt;The schedule for DevTeach 2009 Vancouver has been announced (&lt;a href="http://www.devteach.com/" title="http://www.devteach.com/"&gt;http://www.devteach.com/&lt;/a&gt;).&amp;nbsp; There&amp;rsquo;s lots of great software development sessions from some of the leaders in our industry.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re planning on improving yourself, this is the conference to go to.&amp;nbsp; Not only can you attend excellent sessions; but you can hob-knob with the presenters and pick their brains.&lt;/p&gt;
&lt;p&gt;If you have a friend or co-worker who&amp;rsquo;s interested, there&amp;rsquo;s a limited-time two-for-one offer for an even better price: &lt;a href="http://www.devteach.com/Register.aspx" title="http://www.devteach.com/Register.aspx"&gt;http://www.devteach.com/Register.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f26%2fdevteach-2009-vancouver.aspx"&gt;&lt;img border="0" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fmsmvps.com%2fblogs%2fpeterritchie%2farchive%2f2009%2f03%2f26%2fdevteach-2009-vancouver.aspx" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1681658" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2005/default.aspx">Visual Studio 2005</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+3.x/default.aspx">.NET 3.x</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2008/default.aspx">Visual Studio 2008</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_+3.0/default.aspx">C# 3.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+3.5/default.aspx">.NET 3.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevTeach/default.aspx">DevTeach</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DDD/default.aspx">DDD</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Practices/default.aspx">Software Development Practices</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category></item><item><title>ITSWITCH #1: Answer</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx</link><pubDate>Mon, 28 Jul 2008 19:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1642162</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1642162</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/peterritchie/archive/2008/07/25/itswitch-1.aspx"&gt;Last post&lt;/a&gt; I detailed some code that may or may not have something wrong in it.&amp;#160; If you thought InitializeOne and IntializeTwo are semantically identical (e.g. they differ only by performance), you&amp;#39;d be wrong.&lt;/p&gt;  &lt;p&gt;If you simply ran the code, you&amp;#39;d be able to guess where the problem is.&amp;#160; To understand what&amp;#39;s causing the problem.&amp;#160; Let&amp;#39;s look at how C# effectively implements the two loops.&lt;/p&gt;  &lt;p&gt;InitializeOne is essentially equivalent to&lt;/p&gt;  &lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;   &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PrivateDelegateHelper&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; Value { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Method()&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;TestClass&lt;/span&gt;.ProcessText(Value);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; InitializeThree(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt; cachedAnonymousDelegate = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;PrivateDelegateHelper&lt;/span&gt; privateDelegateHelper = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PrivateDelegateHelper&lt;/span&gt;();&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] copyOfStrings = strings;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt;(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; copyOfStrings.Length; ++i)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; privateDelegateHelper.Value = copyOfStrings;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cachedAnonymousDelegate == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; cachedAnonymousDelegate = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;(privateDelegateHelper.Method);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; delegates.Add(cachedAnonymousDelegate);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now it&amp;#39;s obvious, right?&lt;/p&gt;

&lt;p&gt;For those you don&amp;#39;t want to read all the code, the problem is that only one PrivateDelegateHelper object is instantiated and its value property is set in each iteration of the loop.&amp;#160; Because the delegates aren&amp;#39;t run until sometime after the loop, they&amp;#39;re all run with the last value of the string array as their argument.&lt;/p&gt;

&lt;p&gt;The technical term for what we&amp;#39;ve implemented here is a &lt;a href="http://en.wikipedia.org/wiki/Closure_(computer_science)"&gt;closure&lt;/a&gt;.&amp;#160; If you&amp;#39;re using Resharper 4.x, you would have noticed a warning &amp;quot;Access to modified closure&amp;quot;:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;img height="132" src="http://msmvps.com/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/peterritchie/modified-closure.JPG" width="564" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;...which is attempting to tell you that the closure (the delegate and cached bound variables) has changed (in this case one of the bound variables has changed between the creation of a closure and another and out expected output is effected).&lt;/p&gt;

&lt;p&gt;By the way, you can get the same thing with C# 3+ with lambdas (i.e. you can also write closures with lambdas):&lt;/p&gt;

&lt;div style="border-right:black 1px solid;border-top:black 1px solid;font-size:10pt;background:white;border-left:black 1px solid;color:black;border-bottom:black 1px solid;font-family:courier new;"&gt;
  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; InitializeOne(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;for&lt;/span&gt; (&lt;span style="color:blue;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; strings.Length; ++i)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value = strings;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; delegates.Add(() =&amp;gt; ProcessText(value));&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; InitializeTwo(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; delegates = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value &lt;span style="color:blue;"&gt;in&lt;/span&gt; strings)&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&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;&amp;#160;&amp;#160; delegates.Add(() =&amp;gt; ProcessText(value));&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;

  &lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://msmvps.com/blogs/peterritchie/archive/2008/07/28/itswitch-1-answer.aspx&amp;amp;bgcolor=0080C0&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" border="0/" alt="" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1642162" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pop+Quiz/default.aspx">Pop Quiz</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/ITSWITCH+Answer/default.aspx">ITSWITCH Answer</category></item><item><title>ITSWITCH: #1</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/07/25/itswitch-1.aspx</link><pubDate>Fri, 25 Jul 2008 18:58:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1642154</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1642154</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/07/25/itswitch-1.aspx#comments</comments><description>&lt;p&gt;Is There Something Wrong In This Code Here&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#ff0000;"&gt;UPDATE: as several readers pointed out there was compile error in the code what was being displayed.&amp;nbsp; The line &amp;quot;String value = string&amp;quot; was showing up as &amp;quot;String value = string&amp;quot;.&amp;nbsp; I&amp;#39;m not sure why; but throwing some spaces between the i and the square brackets seems to have solved it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the following class, is there something wrong with either InitializeOne or InitializeTwo (hint, it has nothing to do with compile errors and I&amp;#39;m ignoring&amp;nbsp;performance differences)?&lt;/p&gt;
&lt;div style="font-size:10pt;background:white;color:black;font-family:Courier New;border:black 1px solid;"&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public &lt;/span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TestClass&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt; delegates;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ProcessText(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; text)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;Trace&lt;/span&gt;.WriteLine(text);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Run()&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt; invoker &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; delegates)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; invoker();&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; InitializeOne(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; i = 0; i &amp;lt; strings.Length; ++i)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value = strings[ i ];&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates.Add(&lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; { ProcessText(value); });&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; InitializeTwo(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt;[] strings)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;MethodInvoker&lt;/span&gt;&amp;gt;(strings.Length);&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;String&lt;/span&gt; value &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; strings)&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; delegates.Add(&lt;span style="color:#0000ff;"&gt;delegate&lt;/span&gt; { ProcessText(value); });&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;pre style="background:cornsilk;margin:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Answer on Monday.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1642154" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pop+Quiz/default.aspx">Pop Quiz</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/ITSWITCH/default.aspx">ITSWITCH</category></item><item><title>Formatting/parsing for a specific culture redux</title><link>http://msmvps.com/blogs/peterritchie/archive/2008/01/22/formatting-parsing-for-a-specific-culture-redux.aspx</link><pubDate>Tue, 22 Jan 2008 23:35:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1442456</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1442456</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2008/01/22/formatting-parsing-for-a-specific-culture-redux.aspx#comments</comments><description>&lt;p&gt;In &lt;a class="" href="http://msmvps.com/blogs/peterritchie/archive/2007/12/27/formatting-parsing-for-a-specific-culture.aspx"&gt;recent blog post&lt;/a&gt; I detailed how creating a culture via the CultureInfo constructor could actually create a user-overridden culture--which could be completely different than the culture that you&amp;#39;ve requested by name.&amp;nbsp; Fortunately there&amp;#39;s a way of overriding the user override (apologies for&amp;nbsp;overloading &amp;quot;override&amp;quot;) by supplying&amp;nbsp;the boolean value &amp;quot;false&amp;quot; in&amp;nbsp;a CultureInfo overload.&lt;/p&gt;
&lt;p&gt;As &lt;a class="" href="http://gregbeech.com/blogs/tech/"&gt;Greg Beech&lt;/a&gt; &lt;a class="" href="http://msmvps.com/blogs/peterritchie/archive/2007/12/27/formatting-parsing-for-a-specific-culture.aspx#1442156"&gt;commented&lt;/a&gt;, there&amp;#39;s another method to create a culture--&lt;a class="" href="http://msdn2.microsoft.com/en-us/library/system.globalization.cultureinfo.createspecificculture(VS.80).aspx"&gt;System.Globalization.CultureInfo.CreateSpecificCulture&lt;/a&gt;.&amp;nbsp; This sounds like it does exactly what you might expect and creates a &amp;quot;specific&amp;quot; culture.&amp;nbsp; Unfortunately, this method too violates the &lt;a class="" href="http://en.wikipedia.org/wiki/Principle_of_least_astonishment"&gt;principle of least astonishment&lt;/a&gt; and creates a culture that uses the user-overridden values when the culture name matches that of the user&amp;#39;s current culture.&lt;/p&gt;
&lt;p&gt;CreateSpecificCulture does not, as far as I can tell, have an overload/alternative to you allow to to force a &amp;quot;specific&amp;quot; culture, so the problem is much worse with CreateSpecificCulture.&amp;nbsp; I&amp;#39;ve gone ahead and logged a bug for it on Connect: &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=321241"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=321241&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In case you&amp;#39;re wondering why this is more serious, consider the following following block of code that formats a date value as text:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Globalization.&lt;span style="COLOR:#2b91af;"&gt;CultureInfo&lt;/span&gt; ci;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;String&lt;/span&gt; text;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ci = System.Globalization.&lt;span style="COLOR:#2b91af;"&gt;CultureInfo&lt;/span&gt;.CreateSpecificCulture(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;en-us&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; text = &lt;span style="COLOR:#2b91af;"&gt;String&lt;/span&gt;.Format(ci, &lt;span style="COLOR:#a31515;"&gt;&amp;quot;{0:d}&amp;quot;&lt;/span&gt;, &lt;span style="COLOR:#2b91af;"&gt;DateTime&lt;/span&gt;.Now);&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And that text&amp;nbsp;is transmitted to another application (or another session of the same application, e.g. serialization), potentially in another locale, to be&amp;nbsp;parsed with the following&amp;nbsp;block of code:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Globalization.&lt;span style="COLOR:#2b91af;"&gt;CultureInfo&lt;/span&gt; ci;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ci = System.Globalization.&lt;span style="COLOR:#2b91af;"&gt;CultureInfo&lt;/span&gt;.CreateSpecificCulture(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;en-us&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;String&lt;/span&gt; text = ReadRecord();&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;DateTime&lt;/span&gt; now = &lt;span style="COLOR:#2b91af;"&gt;DateTime&lt;/span&gt;.Parse(text, ci);&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If either (or) the user&amp;#39;s current culture is set to &amp;quot;English (United States)&amp;quot;&amp;nbsp;and they&amp;#39;ve overridden the currency format the short date (say from &amp;quot;M/d/yyyy&amp;quot; to &amp;quot;d/M/yyyy&amp;quot;) will randomly result in the wrong date.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1442456" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Framework+Bugs/default.aspx">Framework Bugs</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevCenterPost/default.aspx">DevCenterPost</category></item><item><title>Using Exceptions For Normal Logic Flow</title><link>http://msmvps.com/blogs/peterritchie/archive/2007/10/12/using-exceptions-for-normal-logic-flow.aspx</link><pubDate>Fri, 12 Oct 2007 17:13:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1245236</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1245236</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2007/10/12/using-exceptions-for-normal-logic-flow.aspx#comments</comments><description>&lt;p&gt;The generally accepted wisdom is that you shouldn&amp;#39;t use Exceptions for normal logic flow.&amp;nbsp; Normal logic flow is a bit subjective; but anything that must happen at least once in all known scenarios is normal logic flow.&lt;/p&gt;
&lt;p&gt;Enter XML Serialization in the framework.&amp;nbsp; The framework actually dynamically creates types that perform the actual serialization of a given type and caches that assembly.&amp;nbsp; The next time that type needs to be serialized it reuses that generated type, reflection is minimized and things happen pretty quickly.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s the rub.&amp;nbsp; The framework decides that it must generate the type when Assembly.Load generates an exception.&amp;nbsp; Something like:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Courier New;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Assembly&lt;/span&gt; assembly = &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assembly = &lt;span style="COLOR:#2b91af;"&gt;Assembly&lt;/span&gt;.Load(assemblyName);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;catch&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;Exception&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assembly = GenerateTempAssembly();&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Which means exceptions are being used for normal logic flow, because when the code is first run&amp;nbsp;the exception is thrown. Now, there&amp;#39;s some folks out there (including&amp;nbsp;folks at Microsoft) that will say &amp;quot;what&amp;#39;s wrong with that, it gets the job done doesn&amp;#39;t it?&amp;quot;.&amp;nbsp; Yes, it does get the job done.&amp;nbsp; The problem&amp;nbsp;is there&amp;#39;s at least once that Assembly.Load is going to generate an exception (if you modify the&amp;nbsp;type being serialized it will happen again).&amp;nbsp; Again,&amp;nbsp;some may&amp;nbsp;say, &amp;quot;So what?&amp;quot;.&amp;nbsp; Well, in Visual Studio there is a BindingFailure Managed Debugging Assistant (MDA) that sits there looking for Assembly.Load failures.&amp;nbsp; This will get kicked off and force a break the first time you try to serialize your type and you&amp;#39;re debugging.&amp;nbsp; When you&amp;#39;re using XmlSerializer to serialize many different types and you turn on this MDA (after all, it&amp;#39;s there and does do some good) then you&amp;#39;ll spend a whole bunch of time wading through the BindingFailure MDA.&lt;/p&gt;
&lt;p&gt;This has been occurring since XmlSerializer was created.&amp;nbsp; I say &amp;quot;including folks at Microsoft&amp;quot;, because up until a couple of days ago I thought someone was on this problem (although I can&amp;#39;t find my sources anymore) at Microsoft.&amp;nbsp; But, the problem still occurs in Ocras Beta 2; which means in the past 3-4 years no one has done a thing about this problem.&amp;nbsp; So, I logged a bug about it on Connect (&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304095"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304095&lt;/a&gt;) and it was quickly closed as &amp;quot;By Design&amp;quot;.&lt;/p&gt;
&lt;p&gt;Keep in mind, the &amp;quot;fix&amp;quot; were talking about is simply checking to see if a file exists before trying to load it, something like:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Courier New;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Assembly&lt;/span&gt; assembly;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Debug&lt;/span&gt;.Assert(assemblyName.CodeBase.StartsWith(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;file:///&amp;quot;&lt;/span&gt;, &lt;span style="COLOR:blue;"&gt;true&lt;/span&gt;, System.Globalization.&lt;span style="COLOR:#2b91af;"&gt;CultureInfo&lt;/span&gt;.InvariantCulture));&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;String&lt;/span&gt; path = assemblyName.CodeBase.Substring(8).Replace(&lt;span style="COLOR:#a31515;"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;, &lt;span style="COLOR:#a31515;"&gt;&amp;#39;\\&amp;#39;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (!System.IO.&lt;span style="COLOR:#2b91af;"&gt;File&lt;/span&gt;.Exists(path))&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assembly = GenerateTempAssembly();&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;else&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assembly = &lt;span style="COLOR:#2b91af;"&gt;Assembly&lt;/span&gt;.Load(assemblyName);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;catch&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;Exception&lt;/span&gt;)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assembly = GenerateTempAssembly();&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;...not too tricky...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1245236" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Rant/default.aspx">Rant</category></item><item><title>Who's Referencing Whom?</title><link>http://msmvps.com/blogs/peterritchie/archive/2007/10/12/who-s-referencing-whom.aspx</link><pubDate>Fri, 12 Oct 2007 15:15:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1244908</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1244908</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2007/10/12/who-s-referencing-whom.aspx#comments</comments><description>&lt;p&gt;When developing any sort of application, debugging in inevitable.&amp;nbsp; Sometimes, part of that debugging means trying to figure out why objects haven&amp;#39;t been collected and therefore figuring out what object is referencing the object that has yet to be collected.&lt;/p&gt;
&lt;p&gt;There&amp;#39;s many reasons why you&amp;#39;d want to find out what object is referencing, like suspected memory &amp;quot;leaks&amp;quot;.&lt;/p&gt;
&lt;p&gt;With Visual Studio (and MDbg) you can use a tool called SOS (or Son&amp;nbsp;Of&amp;nbsp;Strike).&amp;nbsp; This is included in the .NET installation.&amp;nbsp; To use SOS you first need to enable unmanaged debugging in your project (Project\Properties, Debug tab, check &amp;quot;Enable unmanaged code debugging&amp;quot; in the &amp;quot;Enable Debuggers&amp;quot; section).&amp;nbsp; Once unmanaged debugging is enabled you can then debug your application.&amp;nbsp; To use SOS once debugging, you need to load the extension (every time a new debugging session is started).&amp;nbsp; Once a breakpoint has been hit, open the Immediate Window and type &lt;font face="courier new,courier"&gt;.load sos&lt;/font&gt;&lt;font face="Arial"&gt; which should result in the following:&lt;/font&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;.load sos&lt;br /&gt;extension C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;With SOS loaded, you can find out if any objects of a particular type are currently in memory with the &amp;quot;dumpheap -type&amp;quot; command, for example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;!dumpheap -type NamespaceName.TypeName&lt;br /&gt;&amp;nbsp;Address&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Size&lt;br /&gt;&lt;font style="BACKGROUND-COLOR:#ffff00;"&gt;012b2db8&lt;/font&gt; 009159c4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 328&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;total 1 objects&lt;br /&gt;Statistics:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MT&amp;nbsp;&amp;nbsp;&amp;nbsp; Count&amp;nbsp;&amp;nbsp;&amp;nbsp; TotalSize Class Name&lt;br /&gt;009159c4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 328 NamespaceName.TypeName&lt;br /&gt;Total 1 objects&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This lists all objects of the requested type, their address, their MethodTable (MT), and the count of each object per MethodTable.&lt;/p&gt;
&lt;p&gt;Once you have the object&amp;#39;s address you can then find out what objects are referencing that particular instance.&amp;nbsp; This is done with the &lt;font face="courier new,courier"&gt;gcroot&lt;/font&gt; command:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face="courier new,courier"&gt;!gcroot &lt;font style="BACKGROUND-COLOR:#ffff00;"&gt;012b2db8&lt;/font&gt;&lt;br /&gt;Note: Roots found on stacks may be false positives. Run &amp;quot;!help gcroot&amp;quot; for&lt;br /&gt;more info.&lt;br /&gt;Error during command: warning! Extension is using a feature which Visual Studio does not implement.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Scan Thread 4756 OSTHread 1294&lt;br /&gt;ESP:12f0dc:Root:012b2db8(WindowsApplication1.Form1)-&amp;gt;&lt;br /&gt;012bb104(WindowsApplication1.Form2)-&amp;gt;&lt;br /&gt;012bb254(System.Collections.Generic.List`1[[NamespaceName.TypeName, WindowsApplication1]])-&amp;gt;&lt;br /&gt;012bc178(System.Object[])-&amp;gt;&lt;br /&gt;012bc16c(NamespaceName.TypeName)&lt;br /&gt;Scan Thread 3496 OSTHread da8&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;In this particular example, the above tells us that our object (&lt;font face="courier new,courier"&gt;012bc16c(NamespaceName.TypeName)&lt;/font&gt;) is referenced by an Object array (&lt;font face="courier new,courier"&gt;012bc178(System.Object[])&lt;/font&gt;), which is referenced by a &lt;font face="courier new,courier"&gt;List&amp;lt;T&amp;gt;&lt;/font&gt; object (&lt;font face="courier new,courier"&gt;012bb254(System.Collections.Generic.List`1[[NamespaceName.TypeName, WindowsApplication1]])&lt;/font&gt;), which is referenced by &lt;font face="courier new,courier"&gt;Form2&lt;/font&gt; (&lt;font face="courier new,courier"&gt;012bb104(WindowsApplication1.Form2)&lt;/font&gt;), which is referenced by a &lt;font face="courier new,courier"&gt;Form1&lt;/font&gt; object(&lt;font face="courier new,courier"&gt;ESP:12f0dc:Root:012b2db8(WindowsApplication1.Form1)&lt;/font&gt;).&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1244908" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2005/default.aspx">Visual Studio 2005</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Thread.Abort is a Sign of a Poorly Designed Program</title><link>http://msmvps.com/blogs/peterritchie/archive/2007/08/22/thead-abort-is-a-sign-of-a-poorly-designed-program.aspx</link><pubDate>Wed, 22 Aug 2007 19:13:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1131490</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1131490</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2007/08/22/thead-abort-is-a-sign-of-a-poorly-designed-program.aspx#comments</comments><description>&lt;p&gt;Continuing the theme of &lt;a class="" href="http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx"&gt;Thead.Sleep is a sign of a poorly designed program&lt;/a&gt;, I&amp;#39;ve been meaning to provide similar detail on Thread.Abort and not just allude to it in other posts like &lt;a class="" href="http://msmvps.com/blogs/peterritchie/archive/2006/10/13/_2700_System.Threading.Thread.Suspend_280029002700_-is-obsolete_3A00_-_2700_Thread.Suspend-has-been-deprecated_2E002E002E00_.aspx"&gt;&amp;#39;System.Threading.Thread.Suspend() is obsolete: &amp;#39;Thread.Suspend has been deprecated...&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Many of the concepts I&amp;#39;ve discussed regarding Thread.Suspend also apply to Thread.Abort, and in much the same way that the ability to terminate a thread has existed for so long that the concept has remained ubiquitous when dealing with threads and it just keeps getting implemented without thought.&amp;nbsp; Thread.Abort is far more unsafe than Thread.Suspend; but, unfortunately Thread.Abort has yet to be deprecated.&lt;/p&gt;
&lt;p&gt;Unlike Thread.Suspend, Thread.Abort stops your thread and it can&amp;#39;t continue afterwards.&amp;nbsp; In the same vein as Thread.Suspend, Thread.Abort doesn&amp;#39;t know anything about your thread, and if&amp;nbsp;your thread isn&amp;#39;t in a try block&amp;nbsp;that handles ThreadAbortException, it just stops it where it is, which may be in the middle of updating a complex invariant.&amp;nbsp; This means the thread&amp;nbsp;can&amp;#39;t continue where the left off like Thread.Suspend and Thread.Resume and can never get that invariant out of that corrupt state (and nothing else can, it has no idea where that thread left off).&lt;/p&gt;
&lt;p&gt;Thread.Abort isn&amp;#39;t a full-blown terminate; it does cause all finally blocks that it knows about to execute before your thread is stopped and won&amp;#39;t terminate your thread while it&amp;#39;s in a catch or finally block.&lt;/p&gt;
&lt;p&gt;There&amp;#39;s several concepts that go along with Thread.Abort.&amp;nbsp; One I&amp;#39;ve already mentioned, the ThreadAbortException exception.&amp;nbsp; Catching ThreadAbortException is conceptually cooperative thread termination.&amp;nbsp; My issue with catching ThreadAbortException is that you&amp;#39;re essentially using exceptions for normal flow of logic; which I don&amp;#39;t agree with.&amp;nbsp; The other concept is critical regions.&amp;nbsp; You might think that wrapping critical code with Thread.BeginCritcalRegion and Thread.EndCriticalRegion will mean your thread won&amp;#39;t be aborted while it&amp;#39;s executing that code.&amp;nbsp; Unfortunately, the .NET Framework doesn&amp;#39;t really us Begin/EndCriticalRegion for anything.&amp;nbsp; But, that&amp;#39;s also not the intention, the intention is to signify to the runtime (currently only SQL Server vNext, I believe, uses that information) that should a Thread.Abort be called on that thread, or an unhandled exception occur, corruption has occurred and it should simply unload the thread&amp;#39;s&amp;nbsp;AppDomain.&lt;/p&gt;
&lt;p&gt;But, the concept of interrupting the thread in the middle of something is really why you should never use Thread.Abort.&amp;nbsp; It&amp;#39;s one thing to interrupt you own code, but Thread.Abort actually as the potential to interrupt lock statements and cause locks not to be unlocked.&amp;nbsp; As &lt;a class="" href="http://www.bluebytesoftware.com/blog/2007/01/30/MonitorEnterThreadAbortsAndOrphanedLocks.aspx"&gt;Joe Duffy points out&lt;/a&gt;, there&amp;#39;s a check when running code on the x86 that makes sure Thread.Abort can&amp;#39;t interrupt between a call to Monitor.Enter when it is adjacent to a protected region.&amp;nbsp; But, on current 64-bit JITs this check does not exist and a thread can be aborted between the call to Monitor.Enter and the start of the protected region.&lt;/p&gt;
&lt;p&gt;Unfortunately, the x86 is not entirely immune.&amp;nbsp; In the C# compiler, when optimizations are turned off, it emits no-ops in various places.&amp;nbsp; I can&amp;#39;t really confirm why, but the prevalent theory is to allow the Visual Debugger to put breakpoints on source code that otherwise wouldn&amp;#39;t have corresponding IL. (like the start brace, for example).&amp;nbsp; Unfortunately there&amp;#39;s a bug in the generation of that IL that means Thread.Abort can cause locks not to be unreleased.&lt;/p&gt;
&lt;p&gt;Eric Lippert &lt;a class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/17/subtleties-of-c-il-codegen.aspx"&gt;recently provided some of the detail of the bug&lt;/a&gt; on his blog.&amp;nbsp; But, essentially, this is what the C# compiler generates for IL code for the lock statement:&lt;br /&gt;&lt;font face="courier new,courier"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;call void [mscorlib]System.Threading.Monitor::Enter(object)&lt;br /&gt;Hole:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nop &lt;br /&gt;StartTry:&amp;nbsp;&amp;nbsp;&amp;nbsp;nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ldstr &amp;quot;in lock&amp;quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;call void [mscorlib]System.Console::WriteLine(string)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;leave.s EndFinally&lt;br /&gt;EndTry:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ldloc.0 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;call void [mscorlib]System.Threading.Monitor::Exit(object)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;endfinally &lt;br /&gt;EndFinally:&amp;nbsp;nop &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ret &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .try StartTry to EntTry finally handler EndTry to EndFinally&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Which is emitted&amp;nbsp;(from both .NET 2.0 and .NET 3.5 Beta 2) for the compilation&amp;nbsp;of the following:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;lock&lt;/span&gt; (locker)&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR:#a31515;"&gt;&amp;quot;in lock&amp;quot;&lt;/span&gt;);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;This means the lock is acquired (call to Monitor.Enter) and a nop (at Hole) is executed before the start of the protected region (try block).&amp;nbsp; This means there&amp;#39;s an instruction after the acquisition of the lock that isn&amp;#39;t in the try block.&amp;nbsp; It&amp;#39;s at that point if Thread.Abort were called, the finally block would never get executed and the lock would not be released.&amp;nbsp; Likely this would result in deadlocks because nothing can ever release that lock now.&lt;/p&gt;
&lt;p&gt;If you never use Thread.Abort, this issue doesn&amp;#39;t affect you.&amp;nbsp; But, it really just provides another good reason why people keep saying &lt;a class="" href="http://tdanecker.blogspot.com/2007/08/do-never-ever-use-threadabort.html"&gt;you should never use Thread.Abort&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In &lt;a class="" href="http://msmvps.com/blogs/peterritchie/archive/2006/10/13/_2700_System.Threading.Thread.Suspend_280029002700_-is-obsolete_3A00_-_2700_Thread.Suspend-has-been-deprecated_2E002E002E00_.aspx"&gt;&amp;#39;System.Threading.Thread.Suspend() is obsolete: &amp;#39;Thread.Suspend has been deprecated...&lt;/a&gt;. I provide an example of cooperatively terminating a thread, if you&amp;#39;re interested in terminating your thread without using Thread.Abort.&lt;/p&gt;
&lt;p&gt;Like catching Exception, there is an instance when Thread.Abort can be safely used: when you&amp;#39;re terminating your application.&amp;nbsp; If you&amp;#39;re terminating your application and you know you have a foreground thread running and it&amp;#39;s not responding, Thread.Abort can safely be used to ensure your application terminates bcause you&amp;#39;re shutting down and not using any existing invariants or locks.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1131490" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category></item><item><title>Performance Implications of try/catch/finally, Part Two</title><link>http://msmvps.com/blogs/peterritchie/archive/2007/07/12/performance-implications-of-try-catch-finally-part-two.aspx</link><pubDate>Fri, 13 Jul 2007 02:30:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1018297</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1018297</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2007/07/12/performance-implications-of-try-catch-finally-part-two.aspx#comments</comments><description>&lt;p&gt;In a previous blog entry &lt;a class="" href="http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx"&gt;Performance Implications of try/catch/finally&lt;/a&gt;&amp;nbsp;I outlined that the conventional wisdom that there are no performance implications to try blocks unless an exception is thrown is false.&amp;nbsp; I have some clarifications and details to add.&lt;/p&gt;
&lt;p&gt;My original tests used academic sample code like this:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; Method( )&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i = 10;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 20;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 30;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; i;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;As&amp;nbsp;written, the&amp;nbsp;optimized instructions generated by the JIT (Just-In-Time compiler) was showing that no optimizations were occurring in the try block&amp;nbsp;in that the only obvious optimization--the assignment of&amp;nbsp;&lt;em&gt;20&lt;/em&gt; to &lt;em&gt;i--&lt;/em&gt;wasn&amp;#39;t optimized&amp;nbsp;away.&lt;/p&gt;
&lt;p&gt;But,&amp;nbsp;I&amp;#39;ve loaded-the-deck, so to speak.&amp;nbsp;&amp;nbsp;Let&amp;#39;s consider what exception handling needs to be able to do.&amp;nbsp; In this case,&amp;nbsp;I&amp;#39;ve explicitly said I need to do something in the event of an exception in the block of code I&amp;#39;ve wrapped with&amp;nbsp;try{}.&amp;nbsp;&amp;nbsp;The JIT takes me at my word and assumes every line in&amp;nbsp;that block could&amp;nbsp;throw an exception.&amp;nbsp; In order for the&amp;nbsp;finally block to get&amp;nbsp;accurate&amp;nbsp;values for the current state--in the event of&amp;nbsp;that exception--it can&amp;#39;t optimize&amp;nbsp;any variables that are used in or past the finally block.&amp;nbsp;In this case &lt;em&gt;10&lt;/em&gt; must first be assigned to &lt;em&gt;i&lt;/em&gt;, then &lt;em&gt;20&lt;/em&gt; must be assigned to &lt;em&gt;i&lt;/em&gt; then &lt;em&gt;30&lt;/em&gt; must be assigned to &lt;em&gt;i&lt;/em&gt; in the sequence specified in the source code; because if those assignments threw an exception, the finally block would need one of the values: &lt;em&gt;10&lt;/em&gt;, &lt;em&gt;20&lt;/em&gt;, or &lt;em&gt;30&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As you might be able to tell, I&amp;#39;ve loaded-the-deck because I don&amp;#39;t have much outside the try block and everything in the try block is used outside of it as well.&amp;nbsp; I haven&amp;#39;t given the JIT much to work with.&amp;nbsp; So, the &amp;quot;no optimizations are performed in try blocks&amp;quot; isn&amp;#39;t entirely accurate.&amp;nbsp; Obviously, in this case, the assignment of &lt;em&gt;10&lt;/em&gt; to &lt;em&gt;i&lt;/em&gt; wasn&amp;#39;t optimized as well.&amp;nbsp; But, the JIT &lt;em&gt;is&lt;/em&gt; smart enough to attempt to optimize within the try block.&amp;nbsp; If we change the sample slightly to this:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; Method( )&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i = 10;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; c = 2;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; c = 3;&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = 20;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 30;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(c);&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; i;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;...the JIT knows that &lt;em&gt;c&lt;/em&gt; is not used outside the&amp;nbsp;try block and proceeds to optimize it away and converts the Sleep statement into &lt;em&gt;Sleep(3)&lt;/em&gt;.&amp;nbsp; Essentially it&amp;#39;s if I had written:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; Method( )&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i = 10;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 20;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 30;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(3);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; i;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;Okay, things aren&amp;#39;t that dire; at least the JIT is doing what it can within the try block.&amp;nbsp; But what about outside the try block; how drastic are the lack of optimizations there?&amp;nbsp; Again, the JIT is smart enough to do what it can. If we change our original sample slightly again:&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; Method( )&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i = 10;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; b = 9;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; b = 7;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 20;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 30;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; b;&lt;/strong&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;We see that the JIT&amp;nbsp;is smart enough to&amp;nbsp;attempt to optimize what&amp;#39;s&amp;nbsp;outside the try block, and essentially results in this:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; Method( )&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i = 10;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; b = 7;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 20;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 30;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; b;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Better, it&amp;#39;s&amp;nbsp;coalesced the writes (&lt;em&gt;7&lt;/em&gt; and &lt;em&gt;9&lt;/em&gt;)&amp;nbsp;to b into a single write (&lt;em&gt;7&lt;/em&gt;);&amp;nbsp;but&amp;nbsp;for some reason it&amp;nbsp;still forces the assignment of &lt;em&gt;7&lt;/em&gt; to &lt;em&gt;b&lt;/em&gt; before the try block.&amp;nbsp; There&amp;#39;s nothing that could see &lt;em&gt;b&lt;/em&gt; until the return, so it should be able to optimize it a bit further to this:&lt;/p&gt;
&lt;div style="FONT-SIZE:10pt;BACKGROUND:white;COLOR:black;FONT-FAMILY:Lucida Console Modified;"&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; Method( )&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;int&lt;/span&gt; i = 10;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;try&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 20;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; i = 30;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;finally&lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:#2b91af;"&gt;Thread&lt;/span&gt;.Sleep(i);&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt; 7;&lt;/p&gt;
&lt;p style="MARGIN:0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;So, while my previous statement wasn&amp;#39;t&amp;nbsp;entirely accurate, I think what the JIT can optimize is&amp;nbsp;neither better nor worse than &amp;quot;no optimizations are performed in try blocks&amp;quot;, just different.&amp;nbsp;You should still pay close attention to what you&amp;#39;re doing in and around try blocks.&lt;/p&gt;
&lt;p&gt;Also, an apples-to-oranges comparison; but methods with try/catch/finally blocks won&amp;#39;t be inlined.&lt;/p&gt;
&lt;p&gt;Having described what the JIT appears to be doing, and the implication that optimizations to variables used before and after will result in only coalesce-ations prior to the try block (i.e. we&amp;#39;ve observed that it won&amp;#39;t optimize away a variable declared before a try block that is not used within the try or the finally); you should not rely on those side-effects.&amp;nbsp; As far a I&amp;#39;m concerned the JIT is free to perform that last optimization I described, and probably many others.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1018297" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category></item><item><title>Performance Implications of try/catch/finally</title><link>http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx</link><pubDate>Fri, 22 Jun 2007 17:38:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:980434</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>24</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=980434</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2007/06/22/performance-implications-of-try-catch-finally.aspx#comments</comments><description>&lt;p&gt;&lt;font size="3"&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri"&gt;The accepted wisdom regarding performance of &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;try&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri"&gt;/&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;catch&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri"&gt;|&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;finally&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri"&gt; in C# has normally been: &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;try&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri"&gt; has no performance side-effects unless an exception is thrown.&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;font size="3"&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;A discussion I was involved in recently caused me to discover some performance implications of try/catch blocks.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri" size="3"&gt;&amp;nbsp;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;The discussion revolved around protecting the volatility of certain members and the cross-thread memory ordering rules during run-time and &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;during just-in-time compilation.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;As it turns out, Microsoft’s x86 .NET 2.0 just-in-time compiler disables optimizations that would affect the CIL order of read/writes in protected blocks (AKA “protected regions”, “guarded blocks”, or “try blocks”).&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;As a result no optimizations are performed in try blocks.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; 
&lt;p&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;As it turns out, there &lt;strong&gt;are&lt;/strong&gt; performance side-effects to try/catch even if no exceptions are thrown.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;In the following academic example:&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;int&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt; count = 1;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeMethod();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; count++;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeOtherMethod();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; count++;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;Console&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;.WriteLine(count);&lt;/span&gt; 
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;The x86 just-in-time compiler will effectively optimize this as follows:&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeMethod();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SomeOtherMethod();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;Console&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;.WriteLine(3);&lt;/span&gt; 
&lt;p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;The end-result is the same but the side-effects (that would normally be only visible in a debugger) are different (e.g. count never has the value 2).&amp;nbsp; &lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;The just-in-time compiler can do this because it knows no other code can see count when it has the value 2.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;Now, wrapping this in a try block, as follows:&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;int&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt; count = 1;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;try&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SomeMethod();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; count++;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SomeOtherMethod();&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; count++;&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:blue;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;finally&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:#2b91af;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;Console&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;.WriteLine(count);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;COLOR:black;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt; 
&lt;p&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;...is not optimized.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;font face="Lucida Console" size="2"&gt;count &lt;/font&gt;will be created, it will have the value 1, it will have the value 2 after the call to &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;SomeMethod&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri" size="3"&gt;, it will have the value 3 after &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;SomeOther&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font face="Calibri" size="3"&gt; method, and will have the value 3 when &lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:&amp;#39;Lucida Console&amp;#39;;mso-ansi-language:EN-CA;"&gt;Console.WriteLine&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt; is called.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;There are two increments that&amp;nbsp;therefore must be performed that are a waste of cycles.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:EN-CA;"&gt;&lt;font size="3"&gt;&lt;font face="Calibri"&gt;So, be careful how you write code in try blocks.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=980434" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category></item><item><title>.NET Framework 2.0 Service Pack 1</title><link>http://msmvps.com/blogs/peterritchie/archive/2007/05/22/net-framework-2-0-service-pack-1.aspx</link><pubDate>Tue, 22 May 2007 17:45:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:919506</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=919506</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2007/05/22/net-framework-2-0-service-pack-1.aspx#comments</comments><description>&lt;p&gt;I noticed mention of .NET Framework 2.0 Service Pack 1 on a Microsoft site today.&lt;/p&gt;
&lt;p&gt;The BCL Team&amp;#39;s latest blog entry &lt;a href="http://blogs.msdn.com/bclteam/archive/2007/05/21/the-regexoptions-compiled-flag-and-slow-performance-on-64-bit-net-framework-2-0-josh-free.aspx"&gt;http://blogs.msdn.com/bclteam/archive/2007/05/21/the-regexoptions-compiled-flag-and-slow-performance-on-64-bit-net-framework-2-0-josh-free.aspx&lt;/a&gt; mentions a fix that will make it into the .NET Framework 2.0 SP 1.&amp;nbsp; Seems an inevitable release of SP1 for .NET Framework 2.0 is pretty official.&lt;br /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=919506" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Interesting+Find/default.aspx">Interesting Find</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2005/default.aspx">Visual Studio 2005</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category></item><item><title>Changing TextBox Text as an Undo-able Action</title><link>http://msmvps.com/blogs/peterritchie/archive/2006/09/10/Changing-TextBox-Text-as-an-Undo_2D00_able-Action.aspx</link><pubDate>Mon, 11 Sep 2006 01:23:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:121762</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=121762</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2006/09/10/Changing-TextBox-Text-as-an-Undo_2D00_able-Action.aspx#comments</comments><description>&lt;P&gt;The &lt;CODE&gt;TextBox&lt;/CODE&gt; class supports undoing the last action--inherited from &lt;CODE&gt;TextBoxBase&lt;/CODE&gt;.&amp;nbsp; Normally the user does this by pressing the undo key (Ctrl-Z if your keyboard doesn't have a specific Undo key) or by selecting "Undo" from the context menu.&amp;nbsp; The last action can also be undone programmatically by calling &lt;CODE&gt;TextBoxBase.Undo()&lt;/CODE&gt; (after calling &lt;CODE&gt;CanUndo()&lt;/CODE&gt; to see if &lt;CODE&gt;Undo()&lt;/CODE&gt; will work).&lt;/P&gt;
&lt;P&gt;Changing the text in a &lt;CODE&gt;TextBox&lt;/CODE&gt; so that the change can be undone is not so obvious though.&amp;nbsp; Changing the &lt;CODE&gt;Text&lt;/CODE&gt; property or the &lt;CODE&gt;SelectedText&lt;/CODE&gt; property is not undo-able.&amp;nbsp; .NET 2.0 added &lt;CODE&gt;TextBox.Paste(String)&lt;/CODE&gt; (not inherited from &lt;CODE&gt;TextBoxBase&lt;/CODE&gt;, it's inherent to &lt;CODE&gt;TextBox&lt;/CODE&gt;) that replaces the currently selected text and is undoable.&amp;nbsp; If you want to replace all the text while allowing the user to undo it, simply call &lt;CODE&gt;TextBoxBase.SelectAll()&lt;/CODE&gt; before &lt;CODE&gt;Paste(Sting)&lt;/CODE&gt;.&amp;nbsp; For example:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT:silver 1px solid;PADDING-RIGHT:2px;BORDER-TOP:silver 1px solid;PADDING-LEFT:2px;FONT-SIZE:10pt;BACKGROUND:cornsilk;PADDING-BOTTOM:2px;MARGIN:2px;BORDER-LEFT:silver 1px solid;COLOR:black;PADDING-TOP:2px;BORDER-BOTTOM:silver 1px solid;FONT-FAMILY:Courier New;"&gt;
&lt;P style="MARGIN:0px;FONT-FAMILY:Courier New;"&gt;textBox.SelectAll();&lt;/P&gt;
&lt;P style="MARGIN:0px;FONT-FAMILY:Courier New;"&gt;textBox.Paste(text);&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;This side-effect, unfortunately, is not documented--which is why it "is not so obvious".&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=121762" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/WinForms/default.aspx">WinForms</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category></item><item><title>Protecting intellectual properties in .NET, Part 1.</title><link>http://msmvps.com/blogs/peterritchie/archive/2006/09/09/Protecting-intellectual-properties-in-.NET_2E00_.aspx</link><pubDate>Sat, 09 Sep 2006 16:17:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:119801</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=119801</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2006/09/09/Protecting-intellectual-properties-in-.NET_2E00_.aspx#comments</comments><description>&lt;p&gt;One thing that bothers many people and organizations about .NET is the ease of which IL code can be re-hydrated into source code (C#/VB/etc.).&amp;nbsp; While this has always been a problem with binaries, IL code is a much smaller set of instructions compared to the instruction sets of today&amp;#39;s processors and is designed around accommodating high-level-language usage patterns--making it easier to translate into high-level source code.&amp;nbsp; Native binaries could always be disassembled and the assembler code&amp;nbsp;be reassembled into another, new, application.&amp;nbsp; But, it was assembler code, and optimized--nearly impossible to translate into a high-level-language,&amp;nbsp;let alone similar to the original code&amp;nbsp;.&amp;nbsp; Everyone seems fine with this because it doesn&amp;#39;t really look like the original code.&amp;nbsp; .NET IL an be re-hydrated into source that is almost identical to the original--sans comments.&lt;/p&gt;&lt;p&gt;One thing you can do with .NET is to force a method to be precompiled to native code.&amp;nbsp; This can be done by attributing the method with a little-known, not well&amp;nbsp;documented&amp;nbsp;attribute: System.Runtime.CompilerServices.MethodImpl and setting the M&lt;font size="2"&gt;ethodCodeType property to System.Runtime.CompilerServices.&lt;/font&gt;&lt;font color="#008080" size="2"&gt;MethodCodeType&lt;/font&gt;&lt;font size="2"&gt;.Native.&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;Some caveats&lt;/font&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;font size="2"&gt;Seems to only work in a FullTrust environment.&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font size="2"&gt;Since native methods can&amp;#39;t be reflected these methods cannot be uses as event handlers&lt;/font&gt;&lt;/li&gt;&lt;li&gt;&lt;font size="2"&gt;May cause some grief for many debuggers.&lt;/font&gt;&lt;/li&gt;&lt;li&gt;The Runtime severely restricts where methods tagged as Native can be loaded. &lt;/li&gt;&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=119801" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+Development/default.aspx">.NET Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development/default.aspx">Software Development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+2.0/default.aspx">.NET 2.0</category></item></channel></rss>