<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Peter Ritchie's MVP Blog</title><link>http://msmvps.com/blogs/peterritchie/default.aspx</link><description>This is not a life-saving device.</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PeterRitchiesMvpBlog" /><feedburner:info uri="peterritchiesmvpblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Introducing EffectiveIoC</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/iPxf38Nk2vw/introducing-effectiveioc.aspx</link><pubDate>Mon, 11 Mar 2013 19:27:03 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1825022</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1825022</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2013/03/11/introducing-effectiveioc.aspx#comments</comments><description>&lt;p&gt;Last week I &lt;a href="https://twitter.com/peterritchie"&gt;tweeted&lt;/a&gt; a few times about writing an IoC container in less than 60 lines of code.&amp;#160; I also &lt;a href="http://bit.ly/Zm1vIM"&gt;blogged&lt;/a&gt; about how I thought the average IoC container was overly complex and didn’t promote DI-friendliness.&lt;/p&gt;  &lt;p&gt;Well, EffectiveIoC is the result of that short spike.&amp;#160; The core ended up being about 60 lines of code (supported type mappings—including open and closed generics—and app.config mappings).&amp;#160; I felt a minimum viable IoC container needed a little more than that, so I’ve also included programmatic configuration and support for instances (effectively singletons).&amp;#160; I’ve also thrown in the ability to map an action to a type to do whatever you want when the type is resolved.&amp;#160; Without all the friendly API, it works out to be about 80-90 lines of code.&lt;/p&gt;  &lt;h2&gt;Why?&lt;/h2&gt;  &lt;p&gt;Well, the project page sums this up nicely.&amp;#160; For the most part, I wanted something that promoted DI-friendly design—which, from my point of view, is constructor injection.&amp;#160; So, EffectiveIoC is very simple.&amp;#160; It supports mapping one type to another (the &lt;em&gt;from&lt;/em&gt; type must be assignable to the &lt;em&gt;to&lt;/em&gt; type) and registering of instances by name (key).&amp;#160; Registering type mappings can be done in app.config:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5136854.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;or in code:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5136868.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;And type instances can be resolved like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5136886.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Instances can also be registered.&amp;#160; In config this can be done like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5136899.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Or in code, like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5136920.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Instances can be resolved by name as follows:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5136930.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;For more information and to view the source, see the GitHub project site: &lt;a title="https://github.com/peteraritchie/effectiveioc" href="http://bit.ly/WEo1xY"&gt;https://github.com/peteraritchie/effectiveioc&lt;/a&gt;&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2013/03/11/introducing-effectiveioc.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1825022" 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+4.0/default.aspx">.NET 4.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.5/default.aspx">.NET 4.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/EffectiveIoC/default.aspx">EffectiveIoC</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2013/03/11/introducing-effectiveioc.aspx</feedburner:origLink></item><item><title>Dependency Injection</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/YQCvtKkHmjA/dependency-injection.aspx</link><pubDate>Fri, 08 Mar 2013 15:14:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1824852</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1824852</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2013/03/08/dependency-injection.aspx#comments</comments><description>&lt;p&gt;Dependency Injection (DI) is a form of Inversion of Control where the instances that one class need are instantiated outside of the class an “injected” into it.&amp;#160; The most common injection is constructor injection.&amp;#160; This is called inversion of control because the control of the dependencies have been inverted from the dependant class instantiating them to another class instantiating them.&amp;#160; e.g. I could write class like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5100667.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Which is perfectly functional, but &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; is now directly dependant on &lt;font face="Courier New"&gt;List&amp;lt;T&amp;gt;&lt;/font&gt; and this type has become an implementation detail of &lt;font face="Courier New"&gt;MyClass&lt;/font&gt;.&amp;#160; If I wanted to use some other implementation of &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt;, I’d have to re-write &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; and fix the tests that broke because of it.&amp;#160; I may want to use another &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt; implementation because I want to test &lt;font face="Courier New"&gt;MyClass&lt;/font&gt;.&amp;#160; As it stands, I have no way of telling if the class does anything successfully.&amp;#160; I could write an &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt; implementation that I can spy on in a test to verify that &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; does what it supposed to do.&amp;#160; The way &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; is written at the moment, I can’t do that.&lt;/p&gt;  &lt;p&gt;Bear in mind, this is a stupid example.&amp;#160; But, it shows inversion of control with types commonly recognizable.&lt;/p&gt;  &lt;p&gt;So, I could invert the control on &lt;font face="Courier New"&gt;IList&amp;lt;T&amp;gt;&lt;/font&gt; and refactor &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; to be DI-friendly.&amp;#160; In this case, it’s fairly simple:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5100727.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Now &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; does not have a direct dependency on &lt;font face="Courier New"&gt;List&amp;lt;T&amp;gt;&lt;/font&gt; and I can give it anything I want.&amp;#160; In production I’d create an instance like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5100734.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Not a whole lot more complex than before.&amp;#160; If I wanted to test &lt;font face="Courier New"&gt;MyClass&lt;/font&gt; in some way, I could give it a spy:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5100751.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;This is considered &lt;em&gt;Poor Man’s IoC&lt;/em&gt;, in that you’re not making use of a framework or a library specifically devoted to IoC.&lt;/p&gt;  &lt;p&gt;Yes, you’d never really do this in real life; but it’s a fairly clear example—with commonly-used types.&lt;/p&gt;  &lt;h2&gt;IoC Containers&lt;/h2&gt;  &lt;p&gt;There’s a plethora of IoC containers for .NET.&amp;#160; They’re all great tools, like StructureMap, Autofac, Ninject, Unity, etc.&amp;#160; Don’t get me wrong, they’re powerful and they do a lot of things.&amp;#160; But, they do a lot of things.&lt;/p&gt;  &lt;p&gt;What do I mean by “they do a lot of things”?&amp;#160; Well, they’re all effectively designed to work with codebases that are not DI-friendly.&amp;#160; They go out of their way to provide features to support DI in any imaginable design.&amp;#160; “What’s wrong with that” you say?&amp;#160; If you’ve got a brownfield project, that’s great—you can likely get testability with code not designed to be testable—which is a good thing.&amp;#160; But, these abilities make us lazy.&amp;#160; We stop designing DI-friendly classes because we know how to use a particular IoC container to get a known level of IoC and/or testability.&amp;#160; We’ve stopped striving for a simpler design, we’ve stopped striving for DI-friendly code.&lt;/p&gt;  &lt;p&gt;If you’re finding that you’re generally using much more than just constructor injection, having reams and reams of config to set up the various instances or lifecycles then you’re probably letting your IoC container do too much for you and your design is suffering.&amp;#160; If someone has to spend days understanding your IoC container and it’s config for you project, you may have defeated the purpose.&lt;/p&gt;  &lt;p&gt;For lots of good advice on DI in .NET, check out &lt;a href="http://blog.ploeh.dk/tags.html#Dependency%20Injection-ref"&gt;http://blog.ploeh.dk/tags.html#Dependency Injection-ref&lt;/a&gt;.&amp;#160; Some of my favourites: &lt;a title="http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/" href="http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/"&gt;http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/&lt;/a&gt;, &lt;a title="http://blog.ploeh.dk/2011/07/28/CompositionRoot/" href="http://blog.ploeh.dk/2011/07/28/CompositionRoot/"&gt;http://blog.ploeh.dk/2011/07/28/CompositionRoot/&lt;/a&gt;, and &lt;a title="http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/" href="http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/"&gt;http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/&lt;/a&gt;&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2013/03/08/dependency-injection.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1824852" 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/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Patterns/default.aspx">Patterns</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2013/03/08/dependency-injection.aspx</feedburner:origLink></item><item><title>Azure Table Storage and the Great Certificate Expiry of 2013</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/xKnQRuDIMR4/azure-table-storage-and-the-great-certificate-expiry-of-2013.aspx</link><pubDate>Fri, 01 Mar 2013 20:47:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1824528</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1824528</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2013/03/01/azure-table-storage-and-the-great-certificate-expiry-of-2013.aspx#comments</comments><description>&lt;p&gt;I won’t get into too much detail about what happened; but on 22-Feb-2013, roughly at 8pm the certificates used for *.table.core.windows.net expired.&amp;#160; The end result was that any application that used Azure Table Storage .NET API (or REST API and used the default certificate validation) began to fail connecting to Azure Table Storage.&amp;#160; More details can be found &lt;a href="http://bit.ly/13rkTrs"&gt;here&lt;/a&gt;.&amp;#160; At the time of this writing there hadn’t been anything published on any root cause analysis.&lt;/p&gt;  &lt;p&gt;The way that SSL/TLS certificates work is that they provide a means where a 3rd party can validate an organization (i.e. a server with a given URL, or range of URLS).&amp;#160; That validation occurs by using the keys within the certificate to sign data from the server.&amp;#160; A client can then be assured that if a trusted 3rd party issued a cert for that specific URL and that cert was used to sign data from that URL, that the data *must* have come from a trusted server.&amp;#160; The validation occurs as part of a “trust chain”.&amp;#160; That chain includes things like checking for revocation of the certificate, the URL, the start date, the expiry date, etc.&amp;#160; The default action is the check the entire chain based on various policies—which includes checking to make sure the certificate hasn’t expired (based on the local time).&lt;/p&gt;  &lt;p&gt;Now, one might argue that “expiry” of a certificate may not be that important.&amp;#160; That’s a specific decision for a specific client of said server.&amp;#160; I’m not going to suggest that ignoring the expiry is a good or a bad thing.&amp;#160; But, you’re well within your rights to come up with your own policy on the “validity” of a certificate from a specific server.&amp;#160; For example, you might ignore the expiry all together, or you may have a two-week grace period, etc. etc.&lt;/p&gt;  &lt;p&gt;So, how would you do that?&amp;#160; &lt;/p&gt;  &lt;p&gt;Fortunately, you can override the server certificate validation in .NET by setting the &lt;font face="Courier New"&gt;ServicePointManager.ServerCertificateValidationCallback&lt;/font&gt; property to some delegate that contains the policy code that you want to use.&amp;#160; For example, if you want to have a two week grace period after expiry, you could set the &lt;font face="Courier New"&gt;ServerCertificateValidationCallback&lt;/font&gt; like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5067594.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Now, any subsequent calls into the Azure Table Storage API will invoke this callback and you can return true if the certificate is expired but still in the grace period.&amp;#160; E.g. the following code will invoke your callback: &lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5061327.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;h2&gt;Caveat&lt;/h2&gt;  &lt;p&gt;Unfortunately, the existing mechanism (without doing SSL/TLS negotiation entirely yourself) of using &lt;font face="Courier New"&gt;ServicePointManager.ServerCertificateValidationCallback&lt;/font&gt; is a global setting, effectively changes the server certificate validation process of every-single TLS stream within a given &lt;font face="Courier New"&gt;AppDomain&lt;/font&gt; (&lt;font face="Courier New"&gt;HttpWebRequest&lt;/font&gt;, &lt;font face="Courier New"&gt;TlsStream&lt;/font&gt;, etc.).&amp;#160; This also means that any other code that feels like it can change the server certificate validation process.&lt;/p&gt;  &lt;p&gt;So, what can you do about this?&amp;#160; Well, nothing to completely eliminate the race condition—&lt;font face="Courier New"&gt;ServicePointManager.ServerCertificateValidationCallback&lt;/font&gt; is simply designed wrong.&amp;#160; But, you can set &lt;font face="Courier New"&gt;ServerCertificateValidationCallback&lt;/font&gt; as close to the operation you want to perform.&amp;#160; But, this means doing that each for and every operation.&amp;#160; Seeing as how the Azure API make take some time before actually invoking a web request there’s a larger potential for race condition than we’d like.&lt;/p&gt;  &lt;p&gt;An alternative is to invoke the REST API for Azure Table Storage and set &lt;font face="Courier New"&gt;ServerCertificateValidationCallback&lt;/font&gt; just before you invoke your web request.&amp;#160; This, of course, is a bit tedious considering there’s an existing .NET API for table storage.&lt;/p&gt;  &lt;h2&gt;Introducing &lt;font face="Courier New"&gt;RestCloudTable&lt;/font&gt;&lt;/h2&gt;  &lt;p&gt;I was interested in working with Azure REST APIs in general; so, I created a simpler .NET API that uses the REST API but also allows you to specify a validation callback that will set &lt;font face="Courier New"&gt;ServerCertificateValidationCallback&lt;/font&gt; immediately before invoking web requests.&amp;#160; This, of course, doesn’t fix the design issue with &lt;font face="Courier New"&gt;ServerCertificateValidationCallback&lt;/font&gt; but reduces the risk of race conditions as much as possible.&lt;/p&gt;  &lt;p&gt;I’ve created a &lt;font face="Courier New"&gt;RestCloudTable&lt;/font&gt; project on GitHub: &lt;a title="https://github.com/peteraritchie/RestCloudTable" href="https://github.com/peteraritchie/RestCloudTable"&gt;https://github.com/peteraritchie/RestCloudTable&lt;/a&gt;.&amp;#160; Feel free to have a look and use it as is, if you like to avoid any potential future Azure Table Storage certificate expiry.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2013/03/01/azure-table-storage-and-the-great-certificate-expiry-of-2013.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1824528" 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+4.0/default.aspx">.NET 4.0</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.5/default.aspx">.NET 4.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Azure/default.aspx">Azure</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2013/03/01/azure-table-storage-and-the-great-certificate-expiry-of-2013.aspx</feedburner:origLink></item><item><title>async/await Tips</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/lSjImhEemzE/async-await-gotchas.aspx</link><pubDate>Wed, 13 Feb 2013 18:02:21 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1823771</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1823771</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2013/02/13/async-await-gotchas.aspx#comments</comments><description>&lt;p&gt;There’s been some really good guidance about &lt;font face="Courier New"&gt;async&lt;/font&gt;/&lt;font face="Courier New"&gt;await&lt;/font&gt; in the past week or two.&amp;#160; I’ve been tinkering away at this post for a while now—based on presentations I’ve been doing, discussions I’ve had with folks at Microsoft, etc.&amp;#160; Now seems like a good idea to post it.&lt;/p&gt;  &lt;p&gt;First, it’s important to understand what the &amp;quot;async&amp;quot; keyword really mean.&amp;#160; At face value &lt;font face="Courier New"&gt;async&lt;/font&gt; doesn’t make a method (anonymous or member) “asynchronous”—the body of the method does that.&amp;#160; What it does mean is that there’s a strong possibility that the body of the method won’t entirely be evaluated when the method returns to the caller.&amp;#160; i.e. it “might” be asynchronous.&amp;#160; What the compiler does is create a state machine that manages the various “awaits” that occur within an &lt;font face="Courier New"&gt;async&lt;/font&gt; method to manage the results and invoking continuations when results &lt;em&gt;are&lt;/em&gt; available.&amp;#160; I’m not going to get into too much detail about the state machine, other than to say the entry to the method is now the creation of that state machine and the initialization of moving from state to state (much like the creation of an enumerable and moving from one element—the state—to the next).&amp;#160; The important part to remember here is that when an &lt;font face="Courier New"&gt;async&lt;/font&gt; method returns, there can be some code that will be evaluated in the future.&lt;/p&gt;  &lt;p&gt;If you’ve ever done any work with &lt;font face="Courier New"&gt;HttpWebRequest&lt;/font&gt; and working with responses (e.g. disposal), you’ll appreciate being able to do this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006272.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;h2&gt;Parallelism&lt;/h2&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;await&lt;/font&gt; is great to declare asynchronous operations in a sequential way.&amp;#160; This allows you to use other sequential syntax like using and &lt;font face="Courier New"&gt;try&lt;/font&gt;/&lt;font face="Courier New"&gt;catch&lt;/font&gt; to deal with common .NET axioms in the axiomatic way.&amp;#160; &lt;font face="Courier New"&gt;await&lt;/font&gt;, in my opinion, is really about allowing user interfaces to support asynchronous operations in an easy way with intuitive code. But, you can also use &lt;font face="Courier New"&gt;await&lt;/font&gt; to wait for parallel operations to complete.&amp;#160; For example, on a two core computer I can start up two tasks in parallel then &lt;font face="Courier New"&gt;await&lt;/font&gt; on both of them (one at a time) to complete:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006034.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;If you run this code you should see the elapsed values (on a two or more core/cpu computer) will be very similar (not 1 second apart).&amp;#160; Contrast the subtle differences to:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006097.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;While you &lt;strong&gt;can&lt;/strong&gt; use await with parallel operations, the subtlety in the differences between sequential asynchronous operations can lead to incorrect code due to misunderstandings.&amp;#160; I suggest paying close attention to how you structure your code so it is in fact doing what you expect it to do.&amp;#160; In most cases, I simply recommend not doing anything “parallel” with &lt;font face="Courier New"&gt;await&lt;/font&gt;.&lt;/p&gt;  &lt;h2&gt;async void&lt;/h2&gt;  &lt;p&gt;The overwhelming &lt;a href="http://bit.ly/157pMEb"&gt;recommendation&lt;/a&gt; is to&lt;strong&gt; avoid async methods that return void&lt;/strong&gt;.&amp;#160; Caveat: the reason async void was made possible by the language teams was the fact that most event handlers return void; but it is sometimes useful for an event handler to be asynchronous (e.g. await another asynchronous method).&amp;#160; If you want to have a method that uses await but doesn’t return anything (e.g. would otherwise be void) you can simply change the void to Task.&amp;#160; e.g.:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006967.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;This tells the compiler that the method doesn’t asynchronously return a value, but can now be awaited:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006983.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;h2&gt;Main&lt;/h2&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Main&lt;/font&gt; can&amp;#39;t be &lt;font face="Courier New"&gt;async&lt;/font&gt;. As we described above an &lt;font face="Courier New"&gt;async&lt;/font&gt; method can return with code that will be evaluated in the future Main returns, the application exits. If you *could* have an &lt;font face="Courier New"&gt;async&lt;/font&gt; &lt;font face="Courier New"&gt;Main&lt;/font&gt;, it would be similar to doing this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/09bd71ecaa6e9454b57c.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;This, depending on the platform, the hardware, and the current load, would mean that the &lt;font face="Courier New"&gt;Console.WriteLine&lt;/font&gt; *might* get executed.&lt;/p&gt;  &lt;p&gt;Fortunately, this is easily fixed by creating a new method (that &lt;em&gt;can&lt;/em&gt; be modified with &lt;font face="Courier New"&gt;async&lt;/font&gt;) then call it from &lt;font face="Courier New"&gt;Main&lt;/font&gt;.&lt;/p&gt;  &lt;h2&gt;Exceptions&lt;/h2&gt;  &lt;p&gt;One of the biggest advantages of &lt;font face="Courier New"&gt;async&lt;/font&gt;/&lt;font face="Courier New"&gt;await&lt;/font&gt; is the ability to write sequential code with multiple asynchronous operations.&amp;#160; Previously this required methods for each continuation (actual methods prior to .NET 2.0 and anonymous methods and lambdas in .NET 2.0 and&amp;#160; .NET 3.5).&amp;#160; Having code span multiple methods (whether they be anonymous or not) meant we couldn’t use axiomatic patterns like &lt;font face="Courier New"&gt;try&lt;/font&gt;/&lt;font face="Courier New"&gt;catch&lt;/font&gt; (not to mention &lt;font face="Courier New"&gt;using&lt;/font&gt;) very effectively—we’d have to check for exceptions in multiple places for the same reason.&lt;/p&gt;  &lt;p&gt;There are some subtle ways exceptions can flow back from &lt;font face="Courier New"&gt;async&lt;/font&gt; methods, but fortunately the sequential nature of programming with await, you may not care.&amp;#160; But, with most things, it&amp;#39; depends.&amp;#160; Most of the time exceptions are caught in the continuation.&amp;#160; This usually means on a thread different from the main (UI) thread.&amp;#160; So, you have to be careful what you do when you process the exception.&amp;#160; For example, given the following two methods.&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5007599.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;And if we wrapped calls to each in &lt;font face="Courier New"&gt;try&lt;/font&gt;/&lt;font face="Courier New"&gt;catch&lt;/font&gt;:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5007623.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5007638.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;In the first case (calling &lt;font face="Courier New"&gt;DoSomething1&lt;/font&gt;) the exception is caught on the same thread that called Start (i.e. before the &lt;font face="Courier New"&gt;await&lt;/font&gt; occurred).&amp;#160; *But*, in the second case (calling &lt;font face="Courier New"&gt;DoSomething2&lt;/font&gt;) the exception is not caught on the same thread as the caller.&amp;#160; So, if you wanted to present information via the UI then you’d have to check to see if you’re on the right thread to display information on the UI (i.e. marshal back to the UI thread, if needed).&lt;/p&gt;  &lt;p&gt;Of course, any method can throw exceptions in the any of the places of the above two methods, so if you need to do something with thread affinity (like work with the UI) you’ll have to check to see if you need to marshal back to the UI thread (&lt;font face="Courier New"&gt;Control.BeginInvoke&lt;/font&gt; or &lt;font face="Courier New"&gt;Dispatcher.Invoke&lt;/font&gt;).&lt;/p&gt;  &lt;h2&gt;Unit testing&lt;/h2&gt;  &lt;p&gt;Unit testing asynchronous code can get a bit hairy.&amp;#160; For the most part, &lt;em&gt;testing&lt;/em&gt; asynchronously is really just testing the compiler and runtime—not something that is recommended (i.e. it doesn’t buy you anything, it’s not your code).&amp;#160; So, for the most part, I recommend people test the &lt;strong&gt;units&lt;/strong&gt; they intend to test.&amp;#160; e.g. test synchronous code.&amp;#160; For example, I could write an asynchronous method that calculates Pi as follows:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006827.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;…which is fairly typical.&amp;#160; Asynchronous code is often the act of running something on a background thread/task.&amp;#160; I *could* then write a test for this that executes code like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006844.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;But, what I really want to test is that Pi is calculated correctly, not that it occurred asynchronously. &lt;em&gt;&lt;/em&gt;In certain circumstances something may *not* executed asynchronously anyway.&amp;#160; So, I generally recommend in cases like this the test actually be:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006859.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;Of course, that may not always be possible.&amp;#160; You may only have an asynchronous way of invoking code, and if you can’t decompose into asynchronous and synchronous parts for testability then using await is likely the easiest option.&amp;#160; But, there’s some things to watch out for.&amp;#160; When writing a test for this asynchronous method you might intuitively write something like this:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006904.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;But, the problem with this method is that the Assert may not occur before the test runner exits.&amp;#160; This method doesn’t tell the runner that it should wait for a result.&amp;#160; It’s effectively &lt;font face="Courier New"&gt;async void&lt;/font&gt; (another area not to use it).&amp;#160; This can easily be fixed by changing the return from &lt;font face="Courier New"&gt;void&lt;/font&gt; to &lt;font face="Courier New"&gt;Task&lt;/font&gt;:&lt;/p&gt;  &lt;p&gt;&lt;script src="https://gist.github.com/peteraritchie/5006931.js"&gt;&lt;/script&gt;&lt;/p&gt;  &lt;p&gt;A *very* subtle change; but this lets the runner know that the test method is “awaitable” and that it should wait for the &lt;font face="Courier New"&gt;Task&lt;/font&gt; to complete before exiting the runner.&amp;#160; &lt;a href="http://www.srtsolutions.com/testing-async-methods-in-c-5"&gt;Apparently&lt;/a&gt; many test runners recognize this and act accordingly so that your tests will actually run and your asynchronous code will be tested.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2013/02/13/async-await-gotchas.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1823771" 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/C_2300_+5/default.aspx">C# 5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.5/default.aspx">.NET 4.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2012/default.aspx">Visual Studio 2012</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/async/default.aspx">async</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2013/02/13/async-await-gotchas.aspx</feedburner:origLink></item><item><title>IDisposable and Class Hierarchies</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/xIXdckCxc-g/idisposable-and-class-hierarchies.aspx</link><pubDate>Mon, 21 Jan 2013 17:11:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1822950</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1822950</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2013/01/21/idisposable-and-class-hierarchies.aspx#comments</comments><description>&lt;p&gt;In my &lt;a href="http://msmvps.com/blogs/peterritchie/archive/2013/01/20/the-dispose-pattern-as-an-anti-pattern.aspx"&gt;previous post&lt;/a&gt;, I showed how the Dispose Pattern is effectively obsolete. But, there&amp;rsquo;s one area that I didn&amp;rsquo;t really cover.&amp;nbsp; What do you do when you want to create a class that implements &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt;, doesn&amp;rsquo;t implement the Dispose Pattern, &lt;strong&gt;and&lt;/strong&gt; will be derived from classes that will also implement disposal?&lt;/p&gt;
&lt;p&gt;The Dispose Pattern covered this by coincidence.&amp;nbsp; Since something that derives from a class that implements the Dispose Pattern simply overrides the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt; method, you effectively have a way to chain disposal from the sub to the base. There&amp;rsquo;s a lot of unrelated chaff that comes along with Dispose Pattern if that&amp;rsquo;s all you need.&amp;nbsp; What if you want to design a base class that implements &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt; and support sub classes that might want to dispose of managed resources?&amp;nbsp; Well, you&amp;rsquo;re not screwed.&lt;/p&gt;
&lt;p&gt;You can simply make your &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable.Dispose&lt;/span&gt; method virtual and a sub can override it before calling the base.&amp;nbsp; For example:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-size:12pt;"&gt;	&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Base&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;	{
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; managedResource;
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; Dispose()
		{
			&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;(managedResource != &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;) managedResource.Dispose();
		}
	}
 
	&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Sub&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Base&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;	{
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; managedResource;
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;override&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; Dispose()
		{
			&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; (managedResource != &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="color:#000000;"&gt;) managedResource.Dispose();
			&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;.Dispose();
		}
	}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;If you don&amp;rsquo;t implement a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;virtual Dispose&lt;/span&gt; and you don&amp;rsquo;t implement the Dispose Pattern, you should&lt;strong&gt; use the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;sealed&lt;/span&gt; modifier on your class&lt;/strong&gt; because you&amp;rsquo;ve effectively made it impossible for base class to dispose of both their resources and the base&amp;rsquo;s resources in all circumstances.&amp;nbsp; In the case of a variable declared as the base class type that holds an instance of a subclassed type (e.g. &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Base base = new Sub()&lt;/span&gt;) only the base &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt; will get invoked (all other cases, the sub &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt; will get called).&lt;/p&gt;
&lt;h2&gt;Caveat&lt;/h2&gt;
&lt;p&gt;If you do have a base class that implements &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt; and doesn&amp;rsquo;t implement a virtual &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt; or implement the Dispose Pattern (e.g. outside of your control) then you&amp;rsquo;re basically screwed in terms of inheritance.&amp;nbsp; In this case, I would prefer composition over inheritance.&amp;nbsp; The type that would have been the base simply becomes a member of the new class and is treated just like any other disposable member (dealt with in the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable.Dispose&lt;/span&gt; implementation).&amp;nbsp; For example:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-size:12pt;"&gt;	&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Base&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;	{
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/span&gt;
&lt;span style="color:#000000;"&gt;		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; Dispose()
		{
			&lt;/span&gt;&lt;span&gt;&lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;		}
	}
 
	&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Sub&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;	{
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; theBase;
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="color:#000000;"&gt; 
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Dispose()
		{
			theBase.Dispose();
		}
	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;This, of course, means you need to either mirror the interface that the previously-base-class provides, or provide a sub-set of wrapped functionality so the composed object can be used in the same ways it could have been had it been a base class.&lt;/p&gt;
&lt;p&gt;This is why it&amp;rsquo;s important to design consciously&amp;mdash;you need to understand the ramifications and side-effects of certain design choices.&lt;/p&gt;
&lt;div style="margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;iframe style="border:none;width:325px;height:80px;" frameborder="0" scrolling="no" src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2013/01/21/idisposable-and-class-hierarchies.aspx"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div style="margin:0px;padding:0px 0px 0px 0px;" class="wlWriterHeaderFooter"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1822950" 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/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2013/01/21/idisposable-and-class-hierarchies.aspx</feedburner:origLink></item><item><title>The Dispose Pattern as an anti-pattern</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/slAlPW8tvdo/the-dispose-pattern-as-an-anti-pattern.aspx</link><pubDate>Sun, 20 Jan 2013 22:16:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1822917</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>3</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1822917</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2013/01/20/the-dispose-pattern-as-an-anti-pattern.aspx#comments</comments><description>&lt;p&gt;When .NET first came out, the framework only had abstractions for what seemed like a handful of Windows features.&amp;nbsp; Developers were required to write their own abstractions around the Windows features that did not have abstractions.&amp;nbsp; Working with these features required you to work with unmanaged resources in many instances.&amp;nbsp; Unmanaged resources, as the name suggests, are not managed in any way by the .NET Framework.&amp;nbsp; If you don&amp;rsquo;t free those unmanaged resources when you&amp;rsquo;re done with them, they&amp;rsquo;ll leak.&amp;nbsp; Unmanaged resources need attention and they need it differently from managed resources.&amp;nbsp; Managed resources, by definition, are managed by the .NET Framework and their resources will be freed automatically a great proportion of the time when they&amp;rsquo;re no longer in use.&amp;nbsp; The Garbage Collector (GC) knows (or is &amp;ldquo;told&amp;rdquo;) what objects are in use and what objects are not in use.&lt;/p&gt;
&lt;p&gt;The GC frees managed resources when it gets its timeslice(s) to tidy up memory&amp;mdash;which will be some time *after* the resource stop being used.&amp;nbsp; The &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt; interface was created so that managed resources can be deterministically freed.&amp;nbsp; I say &amp;ldquo;managed resources&amp;rdquo; because interfaces can do nothing with destructors and thus the interface inherently can&amp;rsquo;t do anything specifically to help with unmanaged resources.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Unmanaged resources&amp;rdquo; generally means dealing with a handle and freeing that handle when no longer in use.&amp;nbsp; &amp;ldquo;Support&amp;rdquo; for Windows features in .NET abstractions generally involved freeing those handles when not in use.&amp;nbsp; Much like managed resources, to deterministically free them you had to implement &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt; and free them in the call to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt;.&amp;nbsp; The problem with this was if you forgot to wrap the object in a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;using&lt;/span&gt; block or otherwise didn&amp;rsquo;t call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt;.&amp;nbsp; The managed resources would be detected as being unused (unreferenced) and be freed automatically at the next collection, unmanaged resources would not.&amp;nbsp; Unmanaged resources would leak and could cause potential issues with Windows in various ways (handles are a finite resource, for one, so an application could &amp;ldquo;run out&amp;rdquo;).&amp;nbsp; So, those unmanaged resources must be freed during finalization of the object (the automatic cleanup of the object during collection by the GC) had they not already been freed during dispose.&amp;nbsp; Since finalization and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt; are intrinsically linked, the Dispose Pattern was created to make this process easier and consistent.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t get into much detail about the Dispose Pattern, but what this means is that to implement the Dispose Pattern, you must implement a destructor that calls &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt; with a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;false&lt;/span&gt; argument.&amp;nbsp; Destructors that do no work force an entry to be made in the finalize queue for each instance of that type.&amp;nbsp; This forces the type to use its memory until the GC has a chance to collect and run finalizers. This impacts performance (needless finalization) as well as adds stress to the garbage collector (extra work, more things to keep track of, extra resources, etc.). [1] If you have no unmanaged resources to free, you have no reason to have a destructor and thus have no reason to implement the Dispose Pattern.&amp;nbsp; Some might say it&amp;rsquo;s handy &amp;ldquo;just in case&amp;rdquo;; but those cases are &lt;em&gt;really rare&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;.NET has evolved quite a bit from version 1.x, it how has rich support for many of the Windows features that people need to be able to use.&amp;nbsp; Most of the type handles are hidden in these feature abstractions and the developer doesn&amp;rsquo;t need to do anything special other than recognize a type implements &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt; and deterministically call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt; in some way.&amp;nbsp; Of the features that didn&amp;rsquo;t have abstractions, lower-level abstractions like &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;SafeHandle&lt;/span&gt; (which &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;SafeHandleZeroOrMinusOneIsInvalid&lt;/span&gt; and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;SafeHandleMinuesOneIsInvalid&lt;/span&gt; etc. derive from)&amp;mdash;which implement &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;IDisposable&lt;/span&gt; and makes every native handle a &amp;ldquo;managed resource&amp;rdquo;&amp;mdash;means &lt;strong&gt;there is very little reason to write a destructor&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The most recent perpetuation of the anti-pattern is in a Resharper extension called &lt;a href="http://blogs.jetbrains.com/dotnet/2013/01/r2p-a-general-purpose-resharper-plugin/"&gt;R2P&lt;/a&gt; (refactoring to patterns).&amp;nbsp; Let&amp;rsquo;s analyze the example R2P IDisposable code:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blogs.jetbrains.com/dotnet/wp-content/uploads/2012/12/71.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;As we can see from this code, the Dispose pattern has been implemented and a destructor with a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(false)&lt;/span&gt;.&amp;nbsp; If we look at &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt;, &lt;strong&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt; does nothing if a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;false&lt;/span&gt; argument is passed to it&lt;/strong&gt;.&amp;nbsp; So, effectively we could simply remove &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(false)&lt;/span&gt; and get the same result.&amp;nbsp; This also means we could completely remove the destructor.&amp;nbsp; Now we&amp;rsquo;re left with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(true)&lt;/span&gt; in &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose()&lt;/span&gt; and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt;.&amp;nbsp; Since &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt; is now only ever called with a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;true&lt;/span&gt; argument, there&amp;rsquo;s no reason to have this method.&amp;nbsp; We can take the contents of the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;if(disposing)&lt;/span&gt; block, move it to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose&lt;/span&gt; (replacing the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(true)&lt;/span&gt;) and have exactly the same result as before &lt;strong&gt;without the Dispose Pattern&lt;/strong&gt;.&amp;nbsp; Except now, we&amp;rsquo;re reduced the stress on the GC *and* we&amp;rsquo;ve made our code much less complex.&amp;nbsp; Also, since we no longer have a destructor there will be no finalizer, so there&amp;rsquo;s no need to call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;SuppressFinalize&lt;/span&gt;.&amp;nbsp; &lt;strong&gt;Not implementing the Dispose Pattern would result in better code&lt;/strong&gt; in this case:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-size:12pt;"&gt;	&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Person&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : &lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;IDisposable&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;	{
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="color:#000000;"&gt; Dispose()
		{
			Photo.Dispose();
		}
 
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Bitmap&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Photo { &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Of course, when you&amp;rsquo;re &lt;strong&gt;deriving from a class that implements the Dispose Pattern&lt;/strong&gt; &lt;em&gt;and your class needs to dispose of managed resources&lt;/em&gt;, then you need to make use of &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Dispose(bool)&lt;/span&gt;.&amp;nbsp; For example:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;&lt;span style="font-size:12pt;"&gt;	&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;FantasicalControl&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; : System.Windows.Forms.&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Control&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;	{
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;override&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Dispose(&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt; disposing)
		{
			&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="color:#000000;"&gt;(disposing)
			{
				Photo.Dispose();
			}
			&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="font-size:12pt;"&gt;&lt;span style="color:#000000;"&gt;.Dispose(disposing);
		}
		&lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span style="color:#2b91af;"&gt;Bitmap&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt; Photo { &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;; &lt;/span&gt;&lt;span&gt;&lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000000;"&gt;; }
	}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p&gt;Patterns are great, they help document code by providing consistent terminology and recognizable implementation (code).&amp;nbsp; But, when they&amp;rsquo;re not used in the right place at the right time, they make code confusing and harder to understand and become Anti-Patterns.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;[1] &lt;a title="http://bit.ly/YbBDAR" href="http://bit.ly/YbBDAR"&gt;http://bit.ly/YbBDAR&lt;/a&gt;&lt;/p&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2013/01/20/the-dispose-pattern-as-an-anti-pattern.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1822917" 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/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/AntiPattern/default.aspx">AntiPattern</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2013/01/20/the-dispose-pattern-as-an-anti-pattern.aspx</feedburner:origLink></item><item><title>Introduction to Productivity Extensions</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/10VG0CbhpW4/introduction-to-productivity-extensions.aspx</link><pubDate>Fri, 30 Nov 2012 17:12:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1820188</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1820188</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/11/30/introduction-to-productivity-extensions.aspx#comments</comments><description>&lt;p&gt;The .NET Framework has been around since 2002. There are many common classes and methods that have been around a long time. The Framework and the languages used to develop on it have evolved quite a bit since many of these classes and their methods came into existence. Existing classes and methods in the base class library (BCL) could be kept up to date with these technologies, but it&amp;#39;s time consuming and potentially destabilizing to add or change methods after a library has been released and Microsoft generally avoids this unless there&amp;#39;s a &lt;em&gt;really good&lt;/em&gt; reason.&lt;/p&gt;
&lt;p&gt;Generics, for example, came along in the .Net 2.0 timeframe; so, many existing Framework subsystems never had the benefit of generics to make certain methods more strongly-typed. Many methods in the Framework take a &lt;code&gt;Type&lt;/code&gt; parameter and return an&lt;code&gt;Object&lt;/code&gt; of that &lt;code&gt;Type&lt;/code&gt; but must be first cast in order for the object to be used as its requested type.&lt;code&gt;Attribute.GetCustomAttribute(Assembly, Type)&lt;/code&gt; gets an &lt;code&gt;Attribute&lt;/code&gt;-based class that has been added at the assembly level. For example, to get the copyright information of an assembly, you might do something like:&lt;/p&gt;
&lt;pre&gt;var aca = (AssemblyCopyrightAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(),
    typeof (AssemblyCopyrightAttribute));
Trace.WriteLine(aca.Copyright);&lt;/pre&gt;
&lt;p&gt;Involving an &lt;code&gt;Assembly&lt;/code&gt; instance, the &lt;code&gt;Attribute&lt;/code&gt; class, the &lt;code&gt;typeof&lt;/code&gt; operator, and a cast.&lt;/p&gt;
&lt;p&gt;Another feature added after many of the existing APIs were released was &lt;em&gt;anonymous methods&lt;/em&gt;.&amp;nbsp; Anonymous methods will capture outer variables to extend their lifetime so they will be available when the anonymous method is executed (presumably asynchronously to the code where the capture occurred).&amp;nbsp; There are many existing APIs that make the assumption that state can&amp;rsquo;t be captured and it must be managed and passed in explicitly by the caller.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;  //...
  byte[] buffer = new byte[1024];
    fileStream.BeginRead(buffer, 0, buffer.Length, ReadCompleted, fileStream);
  //...

private static void ReadCompleted(IAsyncResult ar)
{
  FileStream fileStream = (FileStream) ar.AsyncState;
    fileStream.EndRead(ar);
    //...
}&lt;/pre&gt;
&lt;p&gt;In this example we&amp;#39;re re-using the &lt;span style="font-family:Courier New;"&gt;stream&lt;/span&gt; (&lt;span style="font-family:Courier New;"&gt;fileStream&lt;/span&gt;) for our state and passing as the state object in the last argument to &lt;code&gt;BeginRead&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With anonymous methods, passing this state in often became unnecessary as the compiler would generate a state machine to manage any variables used within the anonymous method that were declared outside of the anonymous method. For example:&lt;/p&gt;
&lt;pre&gt;fileStream.BeginRead(buffer, 0, buffer.Length, 
  delegate(IAsyncResult ar) { fileStream.EndRead(ar); },
    null);&lt;/pre&gt;
&lt;p&gt;Or, if you prefer the more recent lambda syntax:&lt;/p&gt;
&lt;pre&gt;fileStream.BeginRead(buffer, 0, buffer.Length,
                    ar =&amp;gt; fileStream.EndRead(ar),
                        null);&lt;/pre&gt;
&lt;p&gt;The compiler generates a state machine that captures &lt;span style="font-family:Courier New;"&gt;fileStream&lt;/span&gt; so we don&amp;rsquo;t have to.&amp;nbsp; But, since we&amp;rsquo;re using methods designed prior to &lt;em&gt;out variable capturing&lt;/em&gt;, we have to send &lt;code&gt;null &lt;/code&gt;as the last parameter to tell the method we don&amp;rsquo;t have any state that it needs to pass along. &lt;/p&gt;
&lt;p&gt;Microsoft has a policy of not changing shipped assemblies unless they have to (i.e. bug fixes).&amp;nbsp; This means that just because Generics or anonymous methods were released, they weren&amp;rsquo;t going to go through all the existing classes/methods in already-shipped assemblies and add Generics support or APIs optimized for anonymous methods.&amp;nbsp; Unfortunately, this means many older APIs are harder to use then they need to be.&lt;/p&gt;
&lt;p&gt;Enter Productivity Extensions.&amp;nbsp; When extension methods came along, I would create extension methods to &amp;ldquo;wrap&amp;rdquo; some of these methods in a way that was more convenient with current syntax or features.&amp;nbsp; As a result I had various extension methods lying around that did various things.&amp;nbsp; I decided to collect all those (and others), look at patterns and create a more comprehensive and centralized collection of extension methods&amp;mdash;which I&amp;rsquo;m calling the Productivity Extensions.&lt;/p&gt;
&lt;p&gt;One of those patterns is the Asynchronous Programming Model (APM) and the Begin* methods and their use of the state parameter.&amp;nbsp; Productivity Extensions provide a variety of overrides that simply leave this parameter off and call the original method with &lt;code&gt;null&lt;/code&gt;.&amp;nbsp; For example:&lt;/p&gt;
&lt;pre&gt;fileStream.BeginRead(buffer, 0, buffer.Length,
                    ar =&amp;gt; fileStream.EndRead(ar));&lt;/pre&gt;
&lt;p&gt;In addition, overrides are provided to simply assume offset of 0 and a length that matches the array length.&amp;nbsp; So, using Productivity Extensions you could re-write our original call to &lt;span style="font-family:Courier New;"&gt;BeginRead&lt;/span&gt; as:&lt;/p&gt;
&lt;pre&gt;fileStream.BeginRead(buffer, ar =&amp;gt; fileStream.EndRead(ar));&lt;/pre&gt;
&lt;p&gt;Productivity Extensions also include various extensions to make using older APIs that accept a Type argument and return an Object like Attribute.GetCustomAttribute to make use of Generics.&amp;nbsp; For example:&lt;/p&gt;
&lt;pre&gt;var aca = Assembly.GetExecutingAssembly().GetCustomAttribute&amp;lt;AssemblyCopyrightAttribute&amp;gt;();&lt;/pre&gt;
&lt;p&gt;There&amp;rsquo;s many other instances of these two patterns as well as many other extensions.&amp;nbsp; There&amp;rsquo;s currently 650 methods extending over 400 classes in the .NET Framework.&amp;nbsp; This is completely open source at &lt;a href="http://bit.ly/RMOM0c" title="http://bit.ly/RMOM0c"&gt;http://bit.ly/RMOM0c&lt;/a&gt; and available on NuGet (the ID is &amp;ldquo;ProductivityExtensions&amp;rdquo;) with more information at &lt;a href="http://bit.ly/PDsKcs" title="http://bit.ly/PDsKcs"&gt;http://bit.ly/PDsKcs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I encourage you have a look and if you have any questions, drop me a line, add an issue on GitHub or add suggestions/issues on UserVoice at &lt;a href="http://bit.ly/SkupF9" title="http://bit.ly/SkupF9"&gt;http://bit.ly/SkupF9&lt;/a&gt;.&lt;/p&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe scrolling="no" frameborder="0" src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/11/30/introduction-to-productivity-extensions.aspx" style="width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1820188" 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/Open+Source/default.aspx">Open Source</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2012/default.aspx">Visual Studio 2012</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/11/30/introduction-to-productivity-extensions.aspx</feedburner:origLink></item><item><title>Leave predicting to meteorologists and fortune-tellers</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/i-a1tMQFJq8/leave-predicting-to-meteorologists-and-fortune-tellers.aspx</link><pubDate>Sun, 25 Nov 2012 17:29:29 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1819883</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1819883</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/11/25/leave-predicting-to-meteorologists-and-fortune-tellers.aspx#comments</comments><description>&lt;p&gt;There’s a couple of good axioms about software design: You Can’t Future-Proof Solutions and the Ivory Tower Architect&lt;/p&gt;  &lt;p&gt;&lt;em&gt;You Can’t Future-Proof Solutions&lt;/em&gt; basically details the fact that you can’t predict the future.&amp;#160; You can’t possibly come up with a solution that is “future-proof” without being able to know exactly what will happen in the future.&amp;#160; If you could do that, you shouldn’t be writing software, you should be playing the stock market.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Ivory Tower Architect&lt;/em&gt; is a software development archetype whose attributes are that they are disconnected from the people and users their architecture is supposed to serve.&amp;#160; They don’t know their users because they don’t interact with them and they don’t observe them.&amp;#160; The Ivory Tower Architect’s decisions are based on theory, are academic or esoteric.&amp;#160; Ivory Tower Architects effectively predict what users will want and what will work.&lt;/p&gt;  &lt;p&gt;Prediction is a form of guessing.&amp;#160; At the worst case (fortune tellers) this prediction is actively fraudulent—meant to tell someone something they want to hear to promote their own gain.&amp;#160; At the best case it’s based on past experience and education and is actually turns out true.&amp;#160; Yes, prediction is sometimes right.&amp;#160; But, you don’t want to base anything very important on predictions.&amp;#160; &lt;/p&gt;  &lt;p&gt;Software is a very important aspect of a business.&amp;#160; It takes, time, resources, and money to produce and its success is often gauged by revenue.&amp;#160; Putting time, resources and money into a “guess” is highly risky.&amp;#160; If that guess isn’t accurate, in terms of software, what is produced is technical debt.&amp;#160; If predictions are false the software will not be as useful as needed and will severely impact revenue or cost effectiveness.&amp;#160; &lt;/p&gt;  &lt;p&gt;How do you avoid predictions?&amp;#160; Communicate!&amp;#160; In terms of the ivory tower architect, they shouldn’t work in isolation.&amp;#160; They should at least work with their team.&amp;#160; They should also understand and converse with their customers.&amp;#160; &lt;/p&gt;  &lt;p&gt;All the important information is outside of the organization’s place of business.&amp;#160; You need to understand specific problems and success criteria before you can provide a solution that will work.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/11/25/leave-predicting-to-meteorologists-and-fortune-tellers.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1819883" width="1" height="1"&gt;</description><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/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/11/25/leave-predicting-to-meteorologists-and-fortune-tellers.aspx</feedburner:origLink></item><item><title>And the winners are…</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/IBinNe1fNy4/and-the-winners-are.aspx</link><pubDate>Tue, 06 Nov 2012 19:49:22 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1818869</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1818869</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/11/06/and-the-winners-are.aspx#comments</comments><description>&lt;p&gt;Kevin Davis and by David Williams.&lt;/p&gt;  &lt;p&gt;Please send me an email (via link at left) so I can send you details.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/11/06/and-the-winners-are.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1818869" width="1" height="1"&gt;</description><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/11/06/and-the-winners-are.aspx</feedburner:origLink></item><item><title>Developer Fitness</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/JroSk9qAees/developer-fitness.aspx</link><pubDate>Mon, 05 Nov 2012 21:29:55 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1818846</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1818846</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/11/05/developer-fitness.aspx#comments</comments><description>&lt;p&gt;No, this isn’t something about Fitnesse, it’s really about physical fitness.&amp;#160; Caveat: I’m not a doctor.&lt;/p&gt;  &lt;p&gt;Another conference under my belt: //Build/.&amp;#160; There seems to be a trend of private discussions at conferences (maybe it’s just me) about the sizes of t-shirts at developer conferences and how the average size is, well, above average.&lt;/p&gt;  &lt;p&gt;There seemed to be a few conversations about fitness as well, at least in the context of losing weight.&amp;#160; Let’s be fair, being a developer is not kind to the body.&amp;#160; We sit around, usually inside (in the dark) staring at a computer screen (or screens).&amp;#160; Over-and-above the radiation aspect of this scenario, this means we’re largely sedentary as we perform our jobs.&amp;#160; Not a good thing.&lt;/p&gt;  &lt;p&gt;I’m not big on excuses, yes, our job is sedentary; yes, it doesn’t involve much (if any) physical labour…&amp;#160; But, that’s not an excuse to have a complete lack of exercise in our lives.&amp;#160; I’ve struggled with my weight for years and I came to the conclusion a while back that I didn’t want to be overweight anymore.&amp;#160; I thought it would be useful for me to blog about what I’ve learned over the years.&lt;/p&gt;  &lt;h1&gt;Losing Weight&lt;/h1&gt;  &lt;p&gt;First off, the impetus for better fitness and better health is almost always about losing weight.&amp;#160; That will be the focus of this post.&amp;#160; If you don’t need/want to lose weight, this might be a bit boring.&lt;/p&gt;  &lt;p&gt;Second: diets don’t work.&amp;#160; And by “work” I mean get you to and maintain a healthy weight level.&amp;#160; Yes, a diet will allow you to lose weight for a short period of time—that’s it.&amp;#160; Some diets aren’t even healthy.&amp;#160; I’m not going to mention diets (other than the previous sentence).&amp;#160; If you want to lose weight in the long-term you need to make a lifestyle change—even if it’s just a small amount of weight (in today’s society, a small amount is probably in the range of 25-50 pounds).&amp;#160; If a diet cannot be sustained for the rest of your life and still keep you alive, then it’s a “fad” diet and avoid it.&lt;/p&gt;  &lt;p&gt;I’m not talking about each of us becoming a bodybuilder or a fitness model; let’s get that out of the way: that’s not going to happen, that takes a level of commitment that would interfere with your job (i.e. it would become your full-time job).&amp;#160; But, we can be more healthy and get to a healthier weight and feel better about ourselves.&lt;/p&gt;  &lt;h1&gt;Changing Lifestyle&lt;/h1&gt;  &lt;p&gt;Yes, this means doing things differently in our lives.&amp;#160; Does this mean completely stopping eating certain things?&amp;#160; Not necessarily.&amp;#160; You may have other impetus’ to “stop” certain actions (if you’re diagnosed with high cholesterol cutting out certain foods might be a must); but in general a lifestyle change generally means healthy ratios.&amp;#160; Pizza for example, you can still eat it; just not 3 times a day.&lt;/p&gt;  &lt;p&gt;Down deep in our hearts we really know how to lose weight and keep it off—we just don’t want to admit that we have to reduce certain things and increase others.&amp;#160; We really know that a healthy weight means a certain caloric intake—usually levels lower than where we are, but we just don’t want to admit it.&amp;#160; We’d love it if we could cheat with a diet or pills or hypnosis or surgery or device.&amp;#160; Some people have had “success” at these things; but, “results not typical” is generally somewhere to be found.&lt;/p&gt;  &lt;p&gt;Changing lifestyle can be hard.&amp;#160; I’ve found some various tips and tricks to helping that I’ll outline.&lt;/p&gt;  &lt;h1&gt;Eat more often&lt;/h1&gt;  &lt;p&gt;This simple way of dealing with eating makes overeating and binging less of a problem.&amp;#160; The theory is if you eat 5 meals a day, but make those meals smaller, that your body will think you’re actually eating more.&amp;#160; When you *do* eat, you won’t be as hungry and you won’t feel the need to eat as much.&amp;#160; The theory is that this “stokes the fire” of your system and avoids periods of time as long as 4 hours between meals can trigger your body to store fat.&amp;#160; Keep in mind, we’re ancient devices that had to survive in situations where we didn’t have food for extended periods of time.&amp;#160; It made sense to eat like a mad person for 3 months and store a lot of fat for the next 3-6 months where food may be scarce.&amp;#160; Face it, we’ve created an environment that is counter to our metabolism.&amp;#160; &lt;/p&gt;  &lt;p&gt;Basically, you’d still have 3 squares, but you’d also include two “snacks”.&amp;#160; I remember when I started doing this; it felt like I was eating all the time and eating way to much.&amp;#160; I ate less in the long run.&amp;#160; Take the calories you would have eaten in the “3 squares” and spread them out to a couple of snacks, one after breakfast, and one after lunch.&amp;#160; Once you get in a habit of doing this you’ll feel less hungry during the day and less likely to binge eat.&amp;#160; It generally takes you and your body 6 weeks to get used to things.&amp;#160; If you try something new, try it for at least 6 weeks before making a decision (unless of course you have sudden and sever side effects).&amp;#160; Also remember that your snacks should be balanced in macro nutrients for them to be as effective as they can be.&lt;/p&gt;  &lt;h1&gt;Macro nutrients&lt;/h1&gt;  &lt;p&gt;Every single eating style pays close attention to the three macro nutrients:&amp;#160; they are Fats, Carbohydrates, and Proteins.&amp;#160; Our body needs each of these macro nutrients to survive.&amp;#160; Most foods have each of these macro nutrients.&amp;#160; Tenderloin is high in protein so you need to eat carbs.&amp;#160; Bacon is high in protein and fat; so you have to eat carbs.&amp;#160; Broccoli is high in carbs so you have to eat it with protein, etc…&amp;#160; Most of the “diet plans” really just have a unique macro nutrient ratio.&amp;#160; USDA (at one time, which might still be true; but they revise that periodically) recommends 18:29:53&amp;#160; (protein:fat:carbohydrate % calories), Atkins is generally :65: Zone is 30:40:30, etc.&amp;#160; I like the macronutrient ratio plans because you can eat anything you want as long as you can apply the ratio.&amp;#160; i.e. it works while being vegan or vegetarian.&amp;#160; There’s other plans like Paleo that approach nutrition more around the fact that we’ve evolved from a point where we didn’t have all the manufactured, engineered and contrived food and focuses on “natural” stuff (although, not vegetarian :)&amp;#160; It’s important not to focus one one macro nutrient and it’s important not to cut out a particular macro nutrient.&amp;#160; e.g. cutting out fat, while sounding good (“fat” is the same word as in “bodyfat”) but could lead to malnutrition.&amp;#160; For example, vitamins like A, D, E and K are *fat soluble* which mean fat needs to be present for them to be absorbed.&amp;#160; If you don’t get enough fat you can end up not absorbing enough A, D, E, or K and lead to health issues.&amp;#160; It’s generally the choice of fat that makes a difference in health/weight-loss.&amp;#160; Yeah, you could have fries with your A, D, E, and K foods (or supplements), but that’s not the *good* fats.&amp;#160; Maybe some guacamole would be better.&lt;/p&gt;  &lt;p&gt;But, no matter hat you read or what you choose, “it depends”.&amp;#160; There’s more to healthy eating that just a magic ratio; metabolism, genetics, etc. play a part.&amp;#160; I can’t stress enough, you need to find something that works for *you*—one of these plans might be right; but don’t assume they’re all right.&lt;/p&gt;  &lt;h1&gt;Supplements&lt;/h1&gt;  &lt;p&gt;No, I’m not talking about roids or some funky anabolic-raising concoction.&amp;#160; I’m talking about things that aren’t food.&amp;#160; Vitamins and minerals is generally what I’m talking about—something that supplements your diet.&amp;#160; It’s hard and emotionally unhealthy for the average person to eat exactly the same thing day after day and get the perfect vitamin and mineral intact (whatever that is)—we need some variety in our lives.&amp;#160; So, it’s hard to make sure we’re eating everything we need to to get the nutrients our body needs every day.&amp;#160; I’ve been supplementing for years, well before doctors and nutritional committees/ministries started accepting it.&amp;#160; Yes, as Sheldon says “it makes expensive pee”.&amp;#160; That is true, but, it also means our body has access to the nutrients it needs to function properly and not do the things it does when it thinks it’s malnourished (like storing fat, spiking blood sugar levels, etc.).&amp;#160; This is an area to be careful about.&amp;#160; Many vitamins need *huge* quantities to be toxic, and some don’t; but some are contraindicated for certain people.&amp;#160; Ginseng, for example—this *isn’t* generally a good thing for people with heart problems.&lt;/p&gt;  &lt;p&gt;Other than hyper-dosing on Vitamin C (which still might be bad if you have ulcers), or simply taking a multivitamin as directed, you should talk to a health professionally before drastically changing supplements.&lt;/p&gt;  &lt;h1&gt;Fibre&lt;/h1&gt;  &lt;p&gt;(aka “Fiber” for my US friends).&amp;#160; While there’s a handful of nutritional plans that take fibre into account, I believe it’s tantamount to the fourth macronutrient.&amp;#160; Some nutritional plans allow you to eat more of the other macro nutrients when more fibre is eat at the same time.&amp;#160; e.g. whole-wheat and white bread are roughly the same in calories; but most diets recommend whole-wheat over white—which is partially because of the extra fibre (some of it also has to do with the different ways your body metabolises each: white metabolises into glycogen faster—which can be stored as fat easier).&amp;#160; Generally, the more fibre something has, the better it is for you.&amp;#160; It’s useful to know things that are high in fibre when you’re eating out so you can make better decisions.&lt;/p&gt;  &lt;h1&gt;Things to cut out&lt;/h1&gt;  &lt;p&gt;Okay, I lied, there’s a few things I would recommend not eating at all.&amp;#160; I don’t drink soda any more.&amp;#160; There’s really nothing of any nutritional benefit to any soda beverage—especially sugar free.&amp;#160; Sugar free, in my mind, is one of the worst things to drink.&amp;#160; There’s studies that suggest it tricks the body into thinking it’s eating something sugary and triggers it to store fat.&amp;#160; Even if you don’t believe these studies, there’s still nothing beneficial to soda—I generally stick to water when I’m thirsty.&amp;#160; Cutting out a single can of soda a day will reduce your calorie intake by up to 50 thousand calories!&amp;#160; That’s the equivalent of 35 meals in a year, or almost 11 full days of eating.&amp;#160; If you’re currently drinking a cola a day, that’s one really easy thing to do to help lose weight.&amp;#160; Another is salt. I don’t cut out foods with *any* amount of salt in them; but avoid really salty foods and don’t add salt to meals.&amp;#160; It’s not healthy for the heart and leads to water retention (we’re hoping to look better not “bloated”, right?).&amp;#160; If you reduce table salt drastically, make sure you don’t run the risk of getting a goiter (amongst other things) from the reduced iodine (which can be countered through eating the right kinds of fish).&lt;/p&gt;  &lt;h1&gt;Let your body help you&lt;/h1&gt;  &lt;p&gt;Muscle takes more calories to maintain that fat; the more muscle you have in your body the more calories are required at rest.&amp;#160; This is useful because if you increase your quantity of muscle and maintain the same level of caloric intake then it’s the same as reducing calories.&amp;#160; Many people recommend bodybuilding as a means to lose weight.&amp;#160; You get an increased level of exercise (some of it cardio) while increasing your muscle mass in order to more easily sustain a health body weight.&amp;#160; This generally means compensating with a higher consumption of protein.&amp;#160; But, it’s not for everyone—if you have heart issues then it may not be a good idea.&amp;#160; If you think that’s something you’d want to try, check with your doctor first—just to be on the safe side.&amp;#160; If found it really hard to start and maintain a pace by which to increase muscle mass on my own.&amp;#160; I hired a training a couple of years ago to jump start that.&amp;#160; I already knew most of the techniques and theory; but, to be on a schedule and be there for someone else (or still pay them) was excellent motivation for people to get going and to maintain a healthy pace.&amp;#160; It’s helpful, if you don’t have a gym buddy, to have a trainer around to spot you to avoid injury.&lt;/p&gt;  &lt;p&gt;Despite what you choose for activity, I believe in “balance”.&amp;#160; If you want to concentrate on increase muscle mass, you should still do some cardio.&amp;#160; it’s good for your heart, helps with endurance, and introduces a changing in pace that can help break up the doldrums of the same type of workout 3-4 times a week.&lt;/p&gt;  &lt;h1&gt;It’s not just about X&lt;/h1&gt;  &lt;p&gt;Where x: fitness, nutrition.&amp;#160; Simply changing your eating habits alone isn’t likely to make a huge positive impact on your health.&amp;#160; Yes, you could eat much less or eat much differently and your weight may change (I’ve seen people gain weight when they start eating “healthy”…) but this tactic alone to lose weight can lead to health problems (i.e. “diets” don’t work).&amp;#160; Same goes for fitness, if you simply start working out, running, jogging, cardio, etc. and don’t change your eating habits you run the risk of the same problems with health.&amp;#160; Your body is not in need of different nutrients to sustain the work you’re making it do and you could run into health problems from lack of appropriate nutrients.&amp;#160; I’m a big proponent of a well-rounded lifestyle (not only in terms of fitness, but that’s another blog post :).&amp;#160; I believe in both health food consumption, but also an active lifestyle.&amp;#160; What activity you want to perform can also mean eating differently, possibly on a daily basis.&amp;#160; The variables are endless and your metabolism affects how you should eat/exercise; I recommend some thorough research on this if you want to get really efficient at it.&lt;/p&gt;  &lt;h1&gt;Cheating&lt;/h1&gt;  &lt;p&gt;Losing weight is goal-oriented.&amp;#160; The final goal is, of course, to have a smaller t-shirt size; but for some of us that’s a long-term goal.&amp;#160; It’s difficult to maintain something without seeing “instant” feedback.&amp;#160; “Cheating” is a common method of maintaining a healthy lifestyle with short-term goals.&amp;#160; As I mentioned earlier you don’t have to cut out certain foods; but you can use them as motivation.&amp;#160; For example, pizza.&amp;#160; Sure, don’t have it once a day; but if it’s your krypronite (like me) have it once a week if you meet your other goals.&lt;/p&gt;  &lt;h1&gt;Health v Mood&lt;/h1&gt;  &lt;p&gt;It’s easy to eat certain foods because you’re in a certain mood.&amp;#160; We tend to resort to comfort foods when, well, we need comfort—when we’re not feeling good about ourselves or something earth-shattering has occurred in our lives.&amp;#160; It’s important to be cognizant of what we eat.&amp;#160; Food is a drug that affects us beyond mood—we need to use that drug properly and not abuse it.&amp;#160; If you’re in a bad mood, try to pay more attention to what you eat.&lt;/p&gt;  &lt;h1&gt;Watch what you eat&lt;/h1&gt;  &lt;p&gt;Healthy eating really gets down to simply knowing what we eat.&amp;#160; Simply knowing that in-the-large, a can of cola a day is the equivalent of 35 meals a day in calories, we can better make decisions in-the-small and maybe choose water over cola.&amp;#160; Choosing to limit soda is a a fairly easy decision to make; deciding what to eat, the quantities to eat and the ratio of macro nutrients to consume can get a little daunting.&amp;#160; Some of the simple decisions that I make throughout the day: whole wheat over white, high-protein, low-fat, avoid starchy carbs, avoid sugary beverages, don’t add fats, etc.&amp;#160; A few simple mantras like this can make your food choices much easier from day to day.&amp;#160; Also, each person is different.&amp;#160; There’s different body types (mesomorph, ectomorph, endomorph) and different genetic backgrounds that can affect your how your body metabolises food.&amp;#160; e.g. certain genetic backgrounds did not have milk in their diet so haven’t evolved to tolerate it in their diet—if you’re this type of person milk-based protein supplements might not be a good idea.&amp;#160; But, what I’m really trying to say is that you need to spend a bit of time through trial and error to figure out what works for you before you can really find a lifestyle that not only works for you, but you’re comfortable with.&lt;/p&gt;  &lt;p&gt;What I like about any particular nutrition plan (Zone, Paleo, veganism, vegetarian, etc.) is that it makes you think about what you eat.&amp;#160; I recommend finding one that works and sticking with it.&amp;#160; And yes, that could mean veganism.&amp;#160; (although it is harder to maintain).&amp;#160; It’s important to pick one you know you can be consistent with.&amp;#160; “falling off the wagon” to many times can lead to disappointment, stress, and gaining even more weight.&amp;#160; &lt;/p&gt;  &lt;h1&gt;Sleep&lt;/h1&gt;  &lt;p&gt;Sleep is important for your health in general; but also for you waistline.&amp;#160; Many studies show that getting a good night sleep helps tremendously with attaining a healthy weight as well as maintaining a healthy weight.&amp;#160; Poor sleeping habits can lead to stress, which can lead to increased cortisol levels which leads to changes in insulin levels which can lead to your body storing fat.&amp;#160; There’s been a few studies out there that suggest it’s healthier to wake up early and go to bed early.&amp;#160; I think that generally puts you in sync with the dusk and dawn and maximizes your sun exposure leading a better mood and less stress.&amp;#160; But, I find it hard to do… (did I mention, I don’t think its “just about X”? :)&lt;/p&gt;  &lt;h1&gt;Diabetes&lt;/h1&gt;  &lt;p&gt;I bring this up not because it’s a very common acquired disease or that more than few friends and family have it.&amp;#160; I bring it up because I think what someone with Type 1 or Type 2 diabetes has to deal with in a day can bring much benefit to the average person.&amp;#160; Diabetics have to constantly deal with blood sugar levels and counter-act spikes and troughs through the manual introduction of insulin.&amp;#160; A non-diabetic person generally has a metabolism that monitors and deals with that automatically.&amp;#160; But, that doesn’t mean the spikes in blood sugar and huge insulin production changes are *good* for people.&amp;#160; If you maintain a healthy blood sugar level through the day and don’t cause your body to spike insulin production levels your body will be under less stress (cortisol) and not be in situations where it wants to store fat rather than burn energy.&amp;#160; (One of the reasons I’ve cut out sodas…)&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;Kind of a brain dump to be sure, and if there’s enough interest I can go deeper in to each section…&amp;#160; But, take on the goal of reducing a conference t-shirt size in the next 6 months or the next conference you hope to attend!&amp;#160; Post back (or send me an email) on your progress.&amp;#160; I’d love to see our community and industry be much more healthy—I want to be able to spend more time with you people, not less.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/11/05/developer-fitness.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1818846" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Non-development/default.aspx">Non-development</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/health_2F00_fitness/default.aspx">health/fitness</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/11/05/developer-fitness.aspx</feedburner:origLink></item><item><title>Win a free copy of Visual Studio 2010 Best Practices</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/lA7-09qLc6I/win-a-free-copy-of-visual-studio-2010-best-practices.aspx</link><pubDate>Tue, 25 Sep 2012 18:58:02 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1817311</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>9</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1817311</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/09/25/win-a-free-copy-of-visual-studio-2010-best-practices.aspx#comments</comments><description>&lt;p&gt;Win A free copy of the &amp;#39;Visual Studio 2010 Best Practices&amp;#39;, just by commenting!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://bit.ly/Px43Pw"&gt;&lt;img style="margin:5px 5px 5px 0px;" src="http://sphotos-a.ak.fbcdn.net/hphotos-ak-ash3/155273_464358956938327_975219555_n.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We’re giving away two ebook editions of Visual Studio 2010 Best Practices.&lt;/p&gt;  &lt;p&gt;All you have to do to win is comment on why you think you should win a copy of the book.&lt;/p&gt;  &lt;p&gt;I’ll pick a winner from the most creative answers in two weeks.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/09/25/win-a-free-copy-of-visual-studio-2010-best-practices.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1817311" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+studio+2010+Best+Practices/default.aspx">Visual studio 2010 Best Practices</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/09/25/win-a-free-copy-of-visual-studio-2010-best-practices.aspx</feedburner:origLink></item><item><title>Thread synchronization of non-atomic invariants in .NET 4.5</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/DfVwzuu-O6Y/thread-synchronization-of-non-atomic-invariants-in-net-4-5.aspx</link><pubDate>Tue, 11 Sep 2012 19:04:02 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1816167</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1816167</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/09/11/thread-synchronization-of-non-atomic-invariants-in-net-4-5.aspx#comments</comments><description>&lt;p&gt;Now that we’ve seen how a singular x86-x64 focus &lt;a href="http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx"&gt;might affect how we can synchronize atomic invariants&lt;/a&gt;, let’s look at non-atomic invariants.&lt;/p&gt;  &lt;p&gt;While an atomic invariant really doesn’t need much in the way of &lt;em&gt;guarding&lt;/em&gt;, non-atomic invariants often do.&amp;#160; The rules by which the invariant is correct are often much more complex.&amp;#160; Ensuring an atomic invariant like &lt;font face="Courier New"&gt;int&lt;/font&gt;, for example is pretty easy: you can’t set it to an invalid value, you just need to make sure the value is visible.&amp;#160; Non-atomic invariants involve data that can’t natively be modified atomically.&amp;#160; The typical case is more than one variable, but can include intrinsic types that are not guaranteed to be modified atomically (like long and decimal).&amp;#160; There is also the fact that not all operations on an atomic type are performed atomically.&lt;/p&gt;  &lt;p&gt;For example, let’s say I want to deal with a latitude longitude pair.&amp;#160; That pair of floating-point values is an invariant, I need to model accesses to that pair as an atomic operation.&amp;#160; If I write to &lt;font face="Courier New"&gt;latitude&lt;/font&gt;, that value shouldn’t be “seen” until I also write to &lt;font face="Courier New"&gt;longitude&lt;/font&gt;.&amp;#160; The following code does not guard that invariant in a concurrent context:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;latitude = 39.73;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;longitude = -86.27;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If somewhere else I changed these values, for example I wanted to change from the location of Indianapolis, IN to Ottawa, ON:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; latitude = 45.4112;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; longitude = -75.6981;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Another thread reading &lt;font face="Courier New"&gt;latitude&lt;/font&gt;/&lt;font face="Courier New"&gt;longitude&lt;/font&gt; if the thread was executing the above code was between line 1 and 2, would read a lat/long for some place near Newark instead of Ottawa or Indianapolis (the two lat/longs being written).&amp;#160; Making these write operations volatile does nothing to help make the operation atomic and thread-safe.&amp;#160; For example, the following is still not thread-safe:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; Thread.VolatileWrite(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; latitude, 45.4112);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; Thread.VolatileWrite(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; longitude, -75.6981);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A thread can still read &lt;font face="Courier New"&gt;latitude&lt;/font&gt; or &lt;font face="Courier New"&gt;longitude&lt;/font&gt; after line 1 executes on another thread and before line 2.&amp;#160; Given two variables that are publicly visible, the only way to make an operation on both “atomic” is to use &lt;font face="Courier New"&gt;lock&lt;/font&gt; or use a synchronization class like &lt;font face="Courier New"&gt;Monitor&lt;/font&gt;, &lt;font face="Courier New"&gt;Semaphore&lt;/font&gt;, &lt;font face="Courier New"&gt;Mutex&lt;/font&gt;, etc.&amp;#160; For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt;(latLongLock)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    latitude = 45.4112;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    longitude = -75.6981;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Considering &lt;font face="Courier New"&gt;latitude&lt;/font&gt; and &lt;font face="Courier New"&gt;longitude&lt;/font&gt; “volatile”, doesn’t help us at all in this situation—we have to use &lt;font face="Courier New"&gt;lock&lt;/font&gt;.&amp;#160; And once we use &lt;font face="Courier New"&gt;lock&lt;/font&gt;, there’s no need to consider the variables volatile, no two threads can be in the same critical region at the same time, and any side-effect resulting from executing that critical region are guaranteed to be visible as soon as the lock is released. (as well any potentially visible side-effects from other threads are guaranteed to be visible as soon as the lock is acquired).&lt;/p&gt;

&lt;p&gt;There are circumstances where you can have loads/stores to different addresses that get reordered in relation to each other (a load can be reordered with older stores to a different memory address).&amp;#160; So, conceptually given two threads executing on different cores/CPUS executing the following code at the same time:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;x = 1;    |    y = 1;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;r1 = y;   |    r2 = x;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This could result in r1 == 0 and r2 == 0 (as described in section 8.2.3.2 of &lt;a href="http://download.intel.com/products/processor/manual/253668.pdf"&gt;Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 3A&lt;/a&gt;) assuming r1 and r2 access was optimized by the compiler to be an register access.&amp;#160; The only way to avoid this would be to force a memory barrier.&amp;#160; The use of &lt;font face="Courier New"&gt;volatile&lt;/font&gt;, as we’ve seen the prior post, is not enough to ensure a memory fence is invoked under all circumstances.&amp;#160; This can be done manually through the use of &lt;font face="Courier New"&gt;Thread.MemoryBarrier&lt;/font&gt;, or through the use of &lt;font face="Courier New"&gt;lock&lt;/font&gt;.&amp;#160; &lt;font face="Courier New"&gt;Thread.MemoryBarrier&lt;/font&gt; is less understood by a wide variety of developers, so using &lt;font face="Courier New"&gt;lock&lt;/font&gt; is almost always what should be used prior to any micro-optimizations.&amp;#160; For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt;(lockObject)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  x = 1;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  r1 = y;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt;(lockObject)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  y = 1;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;  r2 = x;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This basically assumes &lt;font face="Courier New"&gt;x&lt;/font&gt; and &lt;font face="Courier New"&gt;y&lt;/font&gt; are involved in a particular invariant and that invariant needs to be guaranteed through atomic access to the pair of variables—which is done by creating a critical regions of code where only one region can be executing at a time across threads.&lt;/p&gt;

&lt;h3&gt;Revisiting the volatile keyword&lt;/h3&gt;

&lt;p&gt;The first post in this series could have came of as suggesting that &lt;font face="Courier New"&gt;volatile&lt;/font&gt; is always a good thing.&amp;#160; As we’ve seen in the above, that’s not true.&amp;#160; Let me be clear: using &lt;font face="Courier New"&gt;volatile&lt;/font&gt; in what I described previously is an optimization.&amp;#160; It should be a micro-optimization that should be used very, very carefully.&amp;#160; What is an isn’t an atomic invariant isn’t always cut and dry.&amp;#160; Not every operation on an atomic type is an atomic operation.&lt;/p&gt;

&lt;p&gt;Let’s look at some of the problems of &lt;font face="Courier New"&gt;volatile&lt;/font&gt;:&lt;/p&gt;

&lt;p&gt;The first, and arguably the most discussed problem, is that volatile decorates a variable not the use of that variable.&amp;#160; With non-atomic operations on an atomic variable, volatile can give you a false sense of security.&amp;#160; You may &lt;em&gt;think&lt;/em&gt; volatile gives you thread-safe code in all accesses to that variable, but it does not.&amp;#160; For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;volatile&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; counter;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomething()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    counter++;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Although many processors have a single instruction to increment an integer, “there is no guarantee of atomic read-modify-write, such as in the case of increment or decrement” [1].&amp;#160; Despite counter being volatile, there’s no guarantee this operation will be atomic and thus there’s no guarantee that it will be thread-safe.&amp;#160; In the general case, not every type you can use operator++ on is atomic—looking strictly at “counter++;”, you can’t tell if that’s thread-safe..&amp;#160; If counter were of type long, access to counter is no longer atomic and a single instruction to increment it is only possible on some processors (regardless of lock of guarantees that it will be used). If counter were an atomic type, you’d have to check the declaration of the variable to see if it was volatile or not before deciding if it’s potentially thread-safe.&amp;#160;&amp;#160; To make incrementing a variable thread-safe, the &lt;font face="Courier New"&gt;Interlocked&lt;/font&gt; class should be used for supported types:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; counter;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomething()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    System.Threading.Interlocked.Increment(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; counter);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Non-atomic types like &lt;font face="Courier New"&gt;long&lt;/font&gt;, &lt;font face="Courier New"&gt;ulong&lt;/font&gt; (i.e. not supported by &lt;font face="Courier New"&gt;volatile&lt;/font&gt;) are supported by &lt;font face="Courier New"&gt;Interlocked&lt;/font&gt;.&amp;#160; For non-atomic types not supported by &lt;font face="Courier New"&gt;Interlocked&lt;/font&gt;, &lt;font face="Courier New"&gt;lock&lt;/font&gt; is recommended until you’ve verified another method is “better” and works:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;decimal&lt;/span&gt; counter;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; lockObject = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomething()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt;(lockObject)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        counter++;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font face="Courier New"&gt;That is volatile&lt;/font&gt; is problematic because it can only be applied to member fields and only to certain types of member fields.&amp;#160; &lt;/p&gt;

&lt;p&gt;The general consensus is that because &lt;font face="Courier New"&gt;volatile&lt;/font&gt; doesn’t decorate the &lt;em&gt;operations&lt;/em&gt; that are potentially performed in a concurrent context, and doesn’t consistently lead to more efficient code in all circumstances, and passing a &lt;font face="Courier New"&gt;volatile&lt;/font&gt; field by ref circumvents the fields volatility, and would fail if used with non-atomic invariants, and lack of consistency with correctly guarded non-atomic operations, etc.; that the volatile operations should be explicit through the use of &lt;font face="Courier New"&gt;Interlocked&lt;/font&gt;, &lt;font face="Courier New"&gt;Thread.VolatileRead&lt;/font&gt;, &lt;font face="Courier New"&gt;Thread.VolatileWrite&lt;/font&gt;, or the use of &lt;font face="Courier New"&gt;lock&lt;/font&gt;&lt;font face="Verdana"&gt; and not through the use of the &lt;font face="Courier New"&gt;volatile&lt;/font&gt; keyword.&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Concurrent and multithreaded programming is not trivial.&amp;#160; It involves dealing with non-sequential operations through the writing of sequential code.&amp;#160; It’s prone to error and you really have to know the intent of your code in order to decide not only what might be used in a concurrent context as well as what is thread-safe.&amp;#160; i.e. “thread-safe” is application specific.&amp;#160; &lt;/p&gt;

&lt;p&gt;Despite only really having support for x86/x64 “out of the box” in .NET 4.5 (i.e. Visual Studio 2012), the &lt;strong&gt;potential side-effects of assuming an x86/x64 memory model just muddies the waters&lt;/strong&gt;.&amp;#160; I don’t think there is any benefit to writing to a x86/x64 memory model over writing to the .NET memory model.&amp;#160; Nothing I’ve shown really affects existing guidance on writing thread-safe and concurrent code—some of which are detailed in &lt;a href="http://bit.ly/Px43Pw"&gt;Visual Studio 2010 Best Practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Knowing what’s going on at lower levels in any particular situation is good, and anything you do in light of any side-effects should be considered micro-optimizations that should be well scrutinized.&lt;/p&gt;

&lt;p&gt;[1] C# Language Specification § 5.5 Atomicity of variable references&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/09/11/thread-synchronization-of-non-atomic-invariants-in-net-4-5.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1816167" 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/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Multithreaded/default.aspx">Multithreaded</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.5/default.aspx">.NET 4.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Concurrency/default.aspx">Concurrency</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2012/default.aspx">Visual Studio 2012</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/09/11/thread-synchronization-of-non-atomic-invariants-in-net-4-5.aspx</feedburner:origLink></item><item><title>Thread synchronization of atomic invariants in .NET 4.5 clarifications</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/HepG14YzTsg/thread-synchronization-of-atomic-invariants-in-net-4-5-clarifications.aspx</link><pubDate>Mon, 10 Sep 2012 19:26:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1816127</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1816127</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/09/10/thread-synchronization-of-atomic-invariants-in-net-4-5-clarifications.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx"&gt;Thread synchronization of atomic invariants in .NET 4.5&lt;/a&gt; I&amp;rsquo;m presenting my observations of what the compiler does in very narrow context of only on Intel x86 and Intel x64 with a particular version of .NET.&amp;nbsp; You can install SDKs that give you access to compilers to other processors.&amp;nbsp; For example, if you write something for Windows Phone or Windows Store, you&amp;rsquo;ll get compilers for other processors (e.g. ARM) with memory models looser than x86 and x64.&amp;nbsp; That post was only observations in the context of x86 and x64.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;I believe more knowledge is always better; but you have to use that knowledge responsibly.&amp;nbsp; If you know you&amp;rsquo;re only ever going to target x86 or x64 (and you don&amp;rsquo;t if you use AnyCPU even in VS 2012 because some yet-to-be-created processor might be supported in a future version or update to .NET) and you &lt;em&gt;do want to micro-optimize your code&lt;/em&gt;, then that post might give you enough knowledge to do that.&amp;nbsp; Otherwise, take it with a grain of salt.&amp;nbsp; I&amp;rsquo;ll get into a little bit more detail in part 2: Thread synchronization of non-atomic invariants in .NET 4.5 at a future date&amp;mdash;which will include more specific guidance and recommendations.&lt;/p&gt;
&lt;p&gt;In the case were I used a &lt;em&gt;really awkwardly placed&lt;/em&gt; &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt;:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; var lockObject = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!complete)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt;(lockObject)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;     {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;         toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;rsquo;s important to point out the degree of implicit side-effects that this code depends on.&amp;nbsp; One, it assumes that the compiler is smart enough to know that a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;while&lt;/span&gt; loop is the equivalent of a series of sequential statements.&amp;nbsp; e.g. this is effectively equivalent to:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; var lockObject = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (complete == &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt; (lockObject)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;     toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (complete == &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;) &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt; (lockObject)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;     toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum12" style="color:#606060;"&gt;  12:&lt;/span&gt; &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That is, there is the implicit volatile read (e.g. a memory fence, from the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Monitor.Enter&lt;/span&gt; implementation detail) at the start of the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; block and an implicit volatile write (e.g. a memory fence, from the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Monitor.Exit&lt;/span&gt; implementation detail).&lt;/p&gt;
&lt;p&gt;In case it wasn&amp;rsquo;t obvious, you should &lt;strong&gt;never write code like&lt;/strong&gt; this, it&amp;rsquo;s simply an example&amp;mdash;and as I pointed out in the original post, it&amp;rsquo;s confusing to anyone else reading it: &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lockObject&lt;/span&gt; can&amp;rsquo;t be shared amongst threads and the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; block really isn&amp;rsquo;t protecting &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt; and can/likely to get &amp;ldquo;maintained&amp;rdquo; into something that no longer works.&lt;/p&gt;
&lt;p&gt;In the same grain, the same can be said for the original example of this code:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; complete = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;   var t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread (() =&amp;gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;   {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; toggle = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!complete)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt;         Thread.MemoryBarrier();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;         toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum12" style="color:#606060;"&gt;  12:&lt;/span&gt;   });&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum13" style="color:#606060;"&gt;  13:&lt;/span&gt;   t.Start();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum14" style="color:#606060;"&gt;  14:&lt;/span&gt;   Thread.Sleep (1000);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum15" style="color:#606060;"&gt;  15:&lt;/span&gt;   complete = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum16" style="color:#606060;"&gt;  16:&lt;/span&gt;   t.Join();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum17" style="color:#606060;"&gt;  17:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;While this code works, it&amp;rsquo;s not apparently clear that the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier()&lt;/span&gt; is there so that our read of &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;complete&lt;/span&gt; (and not &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt;) isn&amp;rsquo;t optimized into a registry read.&amp;nbsp; Regardless of the degree you might be able to depend on the compiler continuing to do this is up to you.&amp;nbsp; The code is equally as valid and more clear if written to use &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;, except for the fact that &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt; does not support the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Boolean&lt;/span&gt; type.&amp;nbsp; It can be re-written using &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Int32&lt;/span&gt; instead.&amp;nbsp; For example:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; complete = 0; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;   var t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread (() =&amp;gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;   {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; toggle = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (Thread.VolatileRead(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; complete) == 0)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt;         toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt;   });&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum12" style="color:#606060;"&gt;  12:&lt;/span&gt;   t.Start();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum13" style="color:#606060;"&gt;  13:&lt;/span&gt;   Thread.Sleep (1000);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum14" style="color:#606060;"&gt;  14:&lt;/span&gt;   complete = 1; // CORRECTION from 0&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum15" style="color:#606060;"&gt;  15:&lt;/span&gt;   t.Join();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum16" style="color:#606060;"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Which is more clear and shows your intent more explicitly.&lt;/p&gt;
&lt;div style="margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;iframe style="border:none;width:325px;height:80px;" frameborder="0" scrolling="no" src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/09/10/thread-synchronization-of-atomic-invariants-in-net-4-5-clarifications.aspx"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div style="margin:0px;padding:0px 0px 0px 0px;" class="wlWriterHeaderFooter"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1816127" 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/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Multithreaded/default.aspx">Multithreaded</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.5/default.aspx">.NET 4.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Concurrency/default.aspx">Concurrency</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/09/10/thread-synchronization-of-atomic-invariants-in-net-4-5-clarifications.aspx</feedburner:origLink></item><item><title>Thread synchronization of atomic invariants in .NET 4.5</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/Lz71udi8eW0/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx</link><pubDate>Sun, 09 Sep 2012 16:52:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1816066</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1816066</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;ve written before about multi-threaded programming in .NET (C#).&amp;nbsp; Spinning up threads and executing code on another thread isn&amp;#39;t really the hard part.&amp;nbsp; The hard part is synchronization of data between threads.&lt;/p&gt;
&lt;p&gt;Most of what I&amp;#39;ve written about is from a processor agnostic point of view.&amp;nbsp; It&amp;#39;s written from the historical point of view: that .NET supports many processors with varying memory models.&amp;nbsp; The stance has generally been that you&amp;#39;re programming for the .NET memory model and not a particular processor memory model.&lt;/p&gt;
&lt;p&gt;But, that&amp;#39;s no longer entirely true.&amp;nbsp; In 2010 Microsoft basically dropped support for Itanium in both Windows Server and in Visual Studio (&lt;a href="http://blogs.technet.com/b/windowsserver/archive/2010/04/02/windows-server-2008-r2-to-phase-out-itanium.aspx"&gt;http://blogs.technet.com/b/windowsserver/archive/2010/04/02/windows-server-2008-r2-to-phase-out-itanium.aspx)&lt;/a&gt;.&amp;nbsp; In VS 2012 there is no &amp;ldquo;Itanium&amp;rdquo; choice in the project Build options.&amp;nbsp; As far as I can tell, Windows 2008 R2 is the only Windows operating system, still in support, that supports Itanium.&amp;nbsp; And even Windows 2008 R2 for Itanium is not supported for .NET 4.5 (&lt;a href="http://msdn.microsoft.com/en-us/library/8z6watww.aspx"&gt;http://msdn.microsoft.com/en-us/library/8z6watww.aspx)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, what does this mean to really only have the context of running only x86/x64?&amp;nbsp; Well, if you really read the documentation and research the Intel x86 and x64 memory model this could have an impact in how you write multi-threaded code with regard to shared data synchronization.&amp;nbsp; x86 and x64 memory models include guarantees like &amp;ldquo;In a multiple-processor system&amp;hellip;Writes by a single processor are observed in the same order by all processors.&amp;rdquo; &lt;span style="text-decoration:line-through;"&gt;but does&lt;/span&gt;&amp;nbsp;&lt;span style="text-decoration:underline;"&gt;and also&lt;/span&gt; includes guarantees like &amp;ldquo;Loads May Be Reordered with Earlier Stores to Different Locations&amp;rdquo;.&amp;nbsp; What this really means is that a store or a load to a single location won&amp;rsquo;t be reordered with regard to a load or a store to the same location across processors.&amp;nbsp; That is we don&amp;rsquo;t &lt;em&gt;need&lt;/em&gt; fences to ensure a store to a single memory location is &amp;ldquo;seen&amp;rdquo; by all threads or that a load from memory loads the &amp;ldquo;most recent&amp;rdquo; value stored.&amp;nbsp; But, it does mean that in order for &lt;em&gt;multiple stores&lt;/em&gt; to &lt;em&gt;multiple locations&lt;/em&gt; to be viewed by other threads &lt;em&gt;in the same order&lt;/em&gt;, a fence is necessary (or the group of store operations is invoked as an atomic action through the user of synchronization primitives like Monitor.Enter/Exit, lock, Semaphore, etc.) (See section 8.2 Memory Ordering&amp;nbsp; of the &lt;a href="http://download.intel.com/products/processor/manual/253668.pdf"&gt;Intel Software Developer&amp;rsquo;s Manual Volume 3A&lt;/a&gt; found &lt;a href="http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html"&gt;here&lt;/a&gt;).&amp;nbsp; But, that deals with non-atomic invariants which I&amp;rsquo;ll detail in another post.&lt;/p&gt;
&lt;p&gt;To be clear, you could develop to just x86 or just x64 prior to .NET 4.5 and have all the issues I&amp;rsquo;m about to detail.&lt;/p&gt;
&lt;p&gt;Prior to .NET 4.5 you really programmed to the .NET memory model.&amp;nbsp; This has changed over time since ECMA defined it around .NET 2.0; but that model was meant to be a &amp;ldquo;supermodel&amp;rdquo; to deal with the fact that .NET could be deployed to different CPUs with disparate memory models.&amp;nbsp; Most notably was the Itanium memory model.&amp;nbsp; This model is much looser than the Intel x86 memory model and allowed things like a store without a release fence and a load without an acquire fence.&amp;nbsp; This meant that a load or a store might be done only in one CPU&amp;rsquo;s memory cache and wouldn&amp;rsquo;t be flushed to memory until a fence.&amp;nbsp; This also meant that other CPUs (e.g. other threads) may not see the store or may not get the &amp;quot;latest&amp;quot; value with a load.&amp;nbsp; You can explicitly cause release and acquire fences with .NET with things like &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Monitor.Enter&lt;/span&gt;/&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Exit&lt;/span&gt; (&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt;), &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Interlocked&lt;/span&gt; methods, &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier&lt;/span&gt;, &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;/&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;VolatileWrite&lt;/span&gt;, etc.&amp;nbsp; So, it wasn&amp;#39;t a big issue for .NET programmers to write code that would work on an Itanium.&amp;nbsp; For the most part, if you simply guarded all your shared data with a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt;, you were fine.&amp;nbsp; &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; is expensive, so you could optimize things with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;/&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;VolatileWriter&lt;/span&gt; if your shared data was inherently atomic (like a single &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;int&lt;/span&gt;, a single &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Object&lt;/span&gt;, etc) or you could use the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt; keyword (in C#).&amp;nbsp; The conventional wisdom has been to use &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;/&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;VolatileWrite&lt;/span&gt; rather than decorate a field with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt; because you may not need &lt;em&gt;every&lt;/em&gt; access to be &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt; and you don&amp;rsquo;t want to take the performance hit when it doesn&amp;rsquo;t &lt;em&gt;need&lt;/em&gt; to be &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;For example (borrowed from &lt;a href="http://www.lidnug.org/archives.aspx"&gt;Jeffrey Richter&lt;/a&gt;, but slightly modified) shows synchronizing a static member variable with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;/&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;VolatileWrite&lt;/span&gt;:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Program {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt;   &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;int&lt;/span&gt; s_stopworker;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main() {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;     Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Main: letting worker run for 5 seconds&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;     Thread t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread(Worker);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;     t.Start();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     Thread.Sleep(5000);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt;     Thread.VolatileWrite(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; s_stopworker, 1);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt;     Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Main: waiting for worker to stop&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;     t.Join();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt;   }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum12" style="color:#606060;"&gt;  12:&lt;/span&gt;  &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum13" style="color:#606060;"&gt;  13:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Worker(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; o) {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum14" style="color:#606060;"&gt;  14:&lt;/span&gt;     Int32 x = 0;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum15" style="color:#606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt;(Thread.VolatileRead(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; s_stopworker) == 0)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum16" style="color:#606060;"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum17" style="color:#606060;"&gt;  17:&lt;/span&gt;       x++;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum18" style="color:#606060;"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum19" style="color:#606060;"&gt;  19:&lt;/span&gt;   }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum20" style="color:#606060;"&gt;  20:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;Without the call to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileWrite&lt;/span&gt; the processor could reorder the write of 1 to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;s_stopworker&lt;/span&gt; to after the read (assuming we&amp;rsquo;re not developing to on particular processor memory model and we&amp;rsquo;re including Itanium).&amp;nbsp; In terms of the compiler, without &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt; it could cache the value being read from s_stopworker in to a register.&amp;nbsp; For example, removing the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;, the compiler optimizes the comparison of &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;s_stopworker&lt;/span&gt; to 0 in the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;while&lt;/span&gt; to single register (on x86):&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000000  push        ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000001  mov         ebp,esp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000003  mov         eax,dword ptr ds:[00213360h] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000008  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000a  jne         00000010 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000c  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000e  je          0000000C &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000010  pop         ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000011  ret &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The loop is 0000000c to 0000000e (really just testing that the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;eax&lt;/span&gt; register is 0). Using &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;, we&amp;rsquo;d always get a value from a physical memory location:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000000  push        ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000001  mov         ebp,esp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000003  lea         ecx,ds:[00193360h] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000009  call        71070480 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000e  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000010  jne         00000021 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000012  lea         ecx,ds:[00193360h] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000018  call        71070480 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000001d  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000001f  je          00000012 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000021  pop         ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000022  ret &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The loop is now 00000012 to 0000001f, which shows calling &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt; each iteration (location 00000018). But, as we&amp;rsquo;ve seen from the Intel documentation and guidance, we don&amp;rsquo;t really need to call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;VolatileRead&lt;/span&gt;, we just don&amp;rsquo;t want the compiler to optimize the memory access away into a register access. This code &lt;em&gt;works&lt;/em&gt;, but we take the hit of calling &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;VolatileRead&lt;/span&gt; which forces a memory fence through a call to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier&lt;/span&gt; after reading the value.&amp;nbsp; For example, the following code is equivalent:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;while&lt;/span&gt;(s_stopworker == 0)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;  Thread.MemoryBarrier();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;  x++;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And this works equally as well as using &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;, and compiles down to:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000000  push        ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000001  mov         ebp,esp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000003  cmp         dword ptr ds:[002A3360h],0 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000a  jne         0000001A &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000c  &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt; or     dword ptr [esp],0 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000011  cmp         dword ptr ds:[002A3360h],0 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000018  je          0000000C &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000001a  pop         ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000001b  ret &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The loop is now is 0000000c to 00000018. As we can see at 0000000c we have an extra &amp;ldquo;lock or&amp;rdquo; instruction&amp;mdash;which is what the compiler optimizes a call to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier&lt;/span&gt; to. This instruction really just or&amp;rsquo;s 0 with what &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;esp&lt;/span&gt; is pointing to (i.e. &amp;ldquo;nothing&amp;rdquo;, zero or&amp;rsquo;ed with something else does not change the value). But the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; prefix forces a fence and is less expensive than instructions like &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;mfence&lt;/span&gt;. But, based on what we know of the x86/x64 memory model, we&amp;rsquo;re only dealing with a single memory location and we don&amp;rsquo;t &lt;em&gt;need&lt;/em&gt; that &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; prefix&amp;mdash;the inherent memory guarantees of the processor means that our thread can see any and all writes to that memory location without this extra fence. So, what can we do to get rid of it? Well, using &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt; actually results in code that doesn&amp;rsquo;t generate that &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock or&lt;/span&gt; instruction. For example, if we change our code to make &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;s_stopworker&lt;/span&gt; &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt;:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Program {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt;   &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;volatile&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; s_stopworker;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main() {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;     Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Main: letting worker run for 5 seconds&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;     Thread t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread(Worker);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;     t.Start();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     Thread.Sleep(5000);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt;     s_stopworker = 1;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt;     Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Main: waiting for worker to stop&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;     t.Join();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt;   }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum12" style="color:#606060;"&gt;  12:&lt;/span&gt;  &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum13" style="color:#606060;"&gt;  13:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Worker(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; o) {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum14" style="color:#606060;"&gt;  14:&lt;/span&gt;     Int32 x = 0;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum15" style="color:#606060;"&gt;  15:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt;(s_stopworker == 0)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum16" style="color:#606060;"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum17" style="color:#606060;"&gt;  17:&lt;/span&gt;       x++;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum18" style="color:#606060;"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum19" style="color:#606060;"&gt;  19:&lt;/span&gt;   }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum20" style="color:#606060;"&gt;  20:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We tell the compiler that we don&amp;rsquo;t want accesses to s_stopworker optimized.&amp;nbsp; This then compiles down to:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000000  push        ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000001  mov         ebp,esp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000003  cmp         dword ptr ds:[00163360h],0 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000a  jne         00000015 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000c  cmp         dword ptr ds:[00163360h],0 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000013  je          0000000C &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000015  pop         ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000016  ret &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The loop is now 0000000c to 00000013. Notice that we&amp;rsquo;re simply getting the value from memory on each iteration and comparing it to 0. There&amp;rsquo;s no &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock or&lt;/span&gt;. One less instruction and no extra memory fence. Although in many cases it doesn&amp;rsquo;t matter (i.e. you might only do this once, in which case an extra few milliseconds won&amp;rsquo;t hurt and this might be a premature optimization), but using &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock or&lt;/span&gt; with the register optimization is about 992% slower when measured on my computer (or &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt; is 91% faster than using &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier&lt;/span&gt; and probably a bit faster still than use &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt;).&amp;nbsp; This is actually contradictory to conventional wisdom with respect to a .NET memory model that supports Itanium.&amp;nbsp; If you want to support Itanium, every access to a &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt; field would be tantamount to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileRead&lt;/span&gt; or &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.VolatileWrite&lt;/span&gt;, in which case, yes, in scenarios where you don&amp;rsquo;t really need the field to be &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt;, you take a performance hit.&lt;/p&gt;
&lt;p&gt;In .NET 4.5 where Itanium is out of the picture, you might be thinking &amp;ldquo;volatile all the time then!&amp;rdquo;.&amp;nbsp; But, hold on a minute, let&amp;rsquo;s look at another example:&lt;/p&gt;
&lt;p id="codeSnippetWrapper"&gt;&amp;nbsp;&lt;/p&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum1" style="color:#606060;"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum2" style="color:#606060;"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum3" style="color:#606060;"&gt;   3:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; complete = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum4" style="color:#606060;"&gt;   4:&lt;/span&gt;   var t = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread (() =&amp;gt;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum5" style="color:#606060;"&gt;   5:&lt;/span&gt;   {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum6" style="color:#606060;"&gt;   6:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; toggle = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum7" style="color:#606060;"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!complete)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum8" style="color:#606060;"&gt;   8:&lt;/span&gt;     {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum9" style="color:#606060;"&gt;   9:&lt;/span&gt;         Thread.MemoryBarrier();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum10" style="color:#606060;"&gt;  10:&lt;/span&gt;         toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum11" style="color:#606060;"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum12" style="color:#606060;"&gt;  12:&lt;/span&gt;   });&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum13" style="color:#606060;"&gt;  13:&lt;/span&gt;   t.Start();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum14" style="color:#606060;"&gt;  14:&lt;/span&gt;   Thread.Sleep (1000);&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum15" style="color:#606060;"&gt;  15:&lt;/span&gt;   complete = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum16" style="color:#606060;"&gt;  16:&lt;/span&gt;   t.Join();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span id="lnum17" style="color:#606060;"&gt;  17:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This code (borrowed from &lt;a href="http://www.albahari.com/threading/part4.aspx"&gt;Joe Albahari&lt;/a&gt;) will block indefinitely at the call to Thread.Join (line 16) without the call to Thread.MemoryBarrier() (at line 9).&amp;nbsp; &lt;/p&gt;
&lt;p&gt;This code blocks indefinitely without &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier()&lt;/span&gt; on both x86 and x64; but this is due to compiler optimizations, not because of the processor&amp;rsquo;s memory model. We can see this in the disassembly of what the JIT produces for the thread lambda (on x64):&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000000  push        ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000001  mov         ebp,esp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000003  movzx       eax,&lt;span style="color:#0000ff;"&gt;byte&lt;/span&gt; ptr [ecx+4] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000007  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000009  jne         0000000F &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000b  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000d  je          0000000B &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000000f  pop         ebp &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000010  ret &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notice the loop (0000000b to 0000000d), the compiler has optimized access to the variable toggle into a register and doesn&amp;rsquo;t update that register from memory&amp;mdash;identical to what we saw with the member field above. If we see the disassembly when using MemoryBarrier:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000000  movzx       eax,&lt;span style="color:#0000ff;"&gt;byte&lt;/span&gt; ptr [rcx+8] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000004  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000006  jne         0000000000000020 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000008  nop         dword ptr [rax+rax+00000000h] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000010  &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt; or     dword ptr [rsp],0 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000015  movzx       eax,&lt;span style="color:#0000ff;"&gt;byte&lt;/span&gt; ptr [rcx+8] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000019  test        eax,eax &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000001b  je          0000000000000010 &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;0000001d  nop         dword ptr [rax] &lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;00000020  rep ret &lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We see that loop testing &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt; (instructions from 00000010 to 0000001b) grabs the memory value into &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;eax&lt;/span&gt; then tests &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;eax&lt;/span&gt; until it&amp;rsquo;s true (or non-zero). &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;MemoryBarrier&lt;/span&gt; has been optimized to &amp;ldquo;lock or&amp;rdquo; here as well.&lt;/p&gt;
&lt;p&gt;What we&amp;rsquo;re dealing with here is a &lt;strong&gt;local variable&lt;/strong&gt; and &lt;strong&gt;can&amp;rsquo;t use the volatile keyword&lt;/strong&gt;.&amp;nbsp; We could use the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; keyword to get a fence, it couldn&amp;rsquo;t be around the comparison (the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;while&lt;/span&gt;) because that would enclose the entire &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;while&lt;/span&gt; block and would never exit the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; to get the memory fence and thus the compiler believes reads of &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt; aren&amp;rsquo;t guarded by &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt;&amp;rsquo;s implicit fences.&amp;nbsp; We&amp;rsquo;d have to wrap &lt;em&gt;the assignment&lt;/em&gt; to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt; to get the release fence before and the acquire fence after, ala:&lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;div id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;
&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;var lockObject = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;();&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (!complete)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;{&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;lock&lt;/span&gt;(lockObject)&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    {&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;        toggle = !toggle;&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;    }&lt;/pre&gt;

&lt;pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Clearly this &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lock&lt;/span&gt; block isn&amp;rsquo;t really a critical section because the &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;lockObject&lt;/span&gt; instance can&amp;rsquo;t be shared amongst threads.&amp;nbsp; Anyone reading this code is likely going to think &amp;ldquo;WTF?&amp;rdquo;. But, &lt;em&gt;we do&lt;/em&gt; get our fences, and the compiler will not optimize access to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt; to only a register and our code will no longer block at the call to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.Join&lt;/span&gt;.&amp;nbsp; It&amp;rsquo;s apparent that &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Thread.MemoryBarrier&lt;/span&gt; is the better choice in this scenario, it&amp;rsquo;s just more readable and doesn&amp;rsquo;t appear to be poorly written code (i.e. code that only depends on side effects).&lt;/p&gt;
&lt;p&gt;But, you still take the performance hit on &amp;ldquo;lock or&amp;rdquo;.&amp;nbsp; If you want to avoid that, then refactor the local &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;toggle&lt;/span&gt; variable to a field and decorate it with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;volatile&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Although some of this seems like micro-optimizations, but it&amp;rsquo;s not.&amp;nbsp; You have to be careful to &amp;ldquo;synchronize&amp;rdquo; shared atomic data with respect to compiler optimizations, so you might as well pick the best way that works.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In the next post I&amp;rsquo;ll get into synchronizing non-atomic invariants shared amongst threads.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;iframe style="border:none;width:325px;height:80px;" frameborder="0" scrolling="no" src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-in-net-4-5.aspx"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div style="margin:0px;padding:0px 0px 0px 0px;" class="wlWriterHeaderFooter"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1816066" 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/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Multithreaded/default.aspx">Multithreaded</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.5/default.aspx">.NET 4.5</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Concurrency/default.aspx">Concurrency</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx</feedburner:origLink></item><item><title>Visual Studio 2010 Best Practices published</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/MGtv8AH_cpo/visual-studio-2010-best-practices-published.aspx</link><pubDate>Sat, 25 Aug 2012 22:12:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1815504</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1815504</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/08/25/visual-studio-2010-best-practices-published.aspx#comments</comments><description>&lt;p&gt;Most of my spare time in the last few months has been taken up by writing &lt;i&gt;Visual Studio 2010 Best Practices&lt;/i&gt;.&amp;nbsp; This has now been published and is available through publisher (no longer pre-order) at &lt;a href="http://bit.ly/Px43Pw"&gt;http://bit.ly/Px43Pw&lt;/a&gt;.&amp;nbsp; The pre-order price is still available for a limited time.&amp;nbsp; Amazon still has it out of stock; but $39.99 at&amp;nbsp;&lt;a href="http://amzn.to/QDDmF7"&gt;&lt;b&gt;http://&lt;/b&gt;amzn.to/QDDmF7&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The title of the book really doesn&amp;#39;t do the content justice.&amp;nbsp; Least of which is &amp;quot;Best Practices&amp;quot;.&amp;nbsp; Anyone who knows me should know I don&amp;#39;t really like that term.&amp;nbsp; But, hopefully those looking for best practices will read the book and learn from chapter one why &amp;quot;best practice&amp;quot; has problems.&lt;/p&gt;
&lt;p&gt;While it&amp;#39;s called &amp;quot;Visual Studio 2010 Best Practices&amp;quot; it isn&amp;#39;t limited to the UI of Visual Studio (or Visual Studio 2010 really, for that matter).&amp;nbsp; It&amp;#39;s really a set of generally accepted recommended practices based on expertise and experience for any and all developers of .NET (it assumes they use Visual Studio--but many practices deal with general design/development that can be applied almost anywhere).&amp;nbsp; There are some specifics in there about the Visual Studio UI like optimizing Visual Studio settings/configuration, useful features, the correct way to use certain features, etc.&amp;nbsp; But, that&amp;#39;s mostly limited to one chapter.&amp;nbsp; Other chapters include recommended practices regarding C#, SCC, deployment, testing, parallelization/multithreading, distributed applications and web services.&amp;nbsp; From the book overview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learning source code control &lt;/li&gt;
&lt;li&gt;Practices for advanced C# syntax &lt;/li&gt;
&lt;li&gt;Asynchronous programming in C# &lt;/li&gt;
&lt;li&gt;Learn tips for architecting decoupled systems &lt;/li&gt;
&lt;li&gt;Practices for designing multi-threaded and parallel systems &lt;/li&gt;
&lt;li&gt;Practices for designing distributed systems &lt;/li&gt;
&lt;li&gt;Learn better ways of developing web services with WCF &lt;/li&gt;
&lt;li&gt;Learn faster ways to design automated tests &lt;/li&gt;
&lt;li&gt;Tips and tricks to test complex systems &lt;/li&gt;
&lt;li&gt;Understanding proven ways of deploying software systems in Windows&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kind of a mixed bag; but, you have to work within the bounds you&amp;#39;ve been given :).&amp;nbsp; It was limited to about 200 pages; so, of course, I couldn&amp;rsquo;t go into every recommended practice or every useful tidbit that everyone could use&amp;hellip;&lt;/p&gt;
&lt;p&gt;I&amp;#39;d like to thank a few people for helping-out outside of the publisher&amp;#39;s review channel (i.e. they&amp;#39;re not mentioned in the book):&amp;nbsp; Joe Miller, Amir Barylko, and of course all those that offered&amp;hellip;&lt;/p&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe scrolling="no" frameborder="0" src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/08/25/visual-studio-2010-best-practices-published.aspx" style="width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1815504" 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/DevCenterPost/default.aspx">DevCenterPost</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><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Principles/default.aspx">Software Development Principles</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Visual+studio+2010+Best+Practices/default.aspx">Visual studio 2010 Best Practices</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/08/25/visual-studio-2010-best-practices-published.aspx</feedburner:origLink></item><item><title>Automated Testing Isn’t Just for Business Logic</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/Z4gM-Y0XtFY/automated-testing-isn-t-just-for-business-logic.aspx</link><pubDate>Fri, 25 May 2012 17:51:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1810302</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1810302</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/05/25/automated-testing-isn-t-just-for-business-logic.aspx#comments</comments><description>&lt;p&gt;I had a conversation with &lt;a href="http://bit.ly/LAcF5n"&gt;Kelly Sommers&lt;/a&gt; the other day that was partially a short &lt;em&gt;support group session&lt;/em&gt; on the annoying tendencies of development teams to completely lose focus on the architecture and design principles of a system and let the code base devolve into a ball of muddy spaghetti.&lt;/p&gt;
&lt;p&gt;One particular area that we discussed, and it&amp;rsquo;s one area I&amp;rsquo;ve detailed &lt;a href="http://bit.ly/c13trs"&gt;elsewhere&lt;/a&gt;, has to do with layers.&amp;nbsp; Our gripe was that developers seem to completely ignore layering principles once they start coding and introduce cycles, put things in the wrong layer, etc.&amp;nbsp; &lt;strong&gt;A brief recap of layering principles&lt;/strong&gt;:&amp;nbsp; Types in one layer can only access types in the adjacent lower layer.&amp;nbsp; That&amp;rsquo;s it.&amp;nbsp; Types that access types in a layer above are violating layering (or aren&amp;rsquo;t layer) and types that access types in a layer lower than the adjacent lower level (e.g. two layers down) are violating layering.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve blogged about Visual Studio and layers (and &lt;a href="http://bit.ly/MAXJUp"&gt;validation&lt;/a&gt;) before; but not everyone uses the part of Visual Studio or doesn&amp;rsquo;t have that edition of Visual Studio.&amp;nbsp; I mentioned in our conversation it&amp;rsquo;s fairly easy to write unit tests to make these verifications.&amp;nbsp; I&amp;rsquo;ve written tests like this before, but the assumption was that &amp;ldquo;layers&amp;rdquo; were in different assemblies.&amp;nbsp; The verification for this scenario is quite a bit simpler; so, I thought I&amp;rsquo;d tackle a test that verifies layering within a single assembly where namespaces are the scope of layers.&lt;/p&gt;
&lt;p&gt;My initial code used &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Enumerable.Any&lt;/span&gt; to see if any types from a lower layer not adjacent to the current layer where used in this layer or whether any types from any layers above the current layer where used in this layer.&amp;nbsp; This did the validation, but basically left the dev with a &amp;ldquo;test failed and I&amp;rsquo;m not giving you any details&amp;rdquo; message because we couldn&amp;rsquo;t tell where the violation was and what violated it&amp;mdash;which isn&amp;rsquo;t too friendly.&amp;nbsp; So, I expanded it out to detail &lt;strong&gt;all &lt;/strong&gt;the violations.&amp;nbsp; I came up with a utility method &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;ValidateLayerRelationships&lt;/span&gt; would be used as follows:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;public&lt;/span&gt;&amp;nbsp;&lt;span&gt;enum&lt;/span&gt;&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;//&amp;nbsp;Order&amp;nbsp;is&amp;nbsp;important!&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Data,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Domain,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;UI
}
 
[&lt;span&gt;TestMethod&lt;/span&gt;]
&lt;span&gt;public&lt;/span&gt;&amp;nbsp;&lt;span&gt;void&lt;/span&gt;&amp;nbsp;ValidateLayerUsage()
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;relatedNamespaces&amp;nbsp;=&amp;nbsp;&lt;span&gt;new&lt;/span&gt;[]&amp;nbsp;{&amp;nbsp;&lt;span&gt;&amp;quot;PRI.Data&amp;quot;&lt;/span&gt;,&amp;nbsp;&lt;span&gt;&amp;quot;PRI.Domain&amp;quot;&lt;/span&gt;,&amp;nbsp;&lt;span&gt;&amp;quot;PRI.FrontEnd&amp;quot;&lt;/span&gt;,&amp;nbsp;&lt;span&gt;&amp;quot;PRI.ViewModels&amp;quot;&lt;/span&gt;&amp;nbsp;};
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;levelMap&amp;nbsp;=&amp;nbsp;&lt;span&gt;new&lt;/span&gt;&amp;nbsp;&lt;span&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span&gt;string&lt;/span&gt;,&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;&amp;gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{relatedNamespaces[0],&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;.Data},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{relatedNamespaces[1],&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;.Domain},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{relatedNamespaces[2],&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;.UI},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{relatedNamespaces[3],&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;.UI},
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;assemblyFileName&amp;nbsp;=&amp;nbsp;&lt;span&gt;&amp;quot;ClassLibrary.dll&amp;quot;&lt;/span&gt;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ValidateLayerRelationships(levelMap,&amp;nbsp;assemblyFileName);
}&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;In this example I have two namespaces in one layer (the UI layer) &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;FrontEnd&lt;/span&gt; and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;ViewModels&lt;/span&gt; and two other layers with just one namespace in each (&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Data&lt;/span&gt; with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Data&lt;/span&gt; and &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Domain&lt;/span&gt; with &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;Domain&lt;/span&gt;). mostly to show you can have more than one namespace per layer&amp;hellip;&amp;nbsp;&amp;nbsp; We define a layer map, and the filename of the assembly we want to validate and call &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;ValidateLayerRelationships&lt;/span&gt;.&amp;nbsp; &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;ValidateLayerRelationships&lt;/span&gt; is as follows:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="font-size:12pt;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;private&lt;/span&gt;&amp;nbsp;&lt;span&gt;static&lt;/span&gt;&amp;nbsp;&lt;span&gt;void&lt;/span&gt;&amp;nbsp;ValidateLayerRelationships(&lt;span&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span&gt;string&lt;/span&gt;,&amp;nbsp;&lt;span&gt;Layer&lt;/span&gt;&amp;gt;&amp;nbsp;levelMap,&amp;nbsp;&lt;span&gt;string&lt;/span&gt;&amp;nbsp;assemblyFileName)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;//&amp;nbsp;can&amp;#39;t&amp;nbsp;use&amp;nbsp;ReflectionOnlyLoadFrom&amp;nbsp;because&amp;nbsp;we&amp;nbsp;want&amp;nbsp;to&amp;nbsp;peek&amp;nbsp;at&amp;nbsp;attributes&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;groups&amp;nbsp;=&amp;nbsp;&lt;span&gt;from&lt;/span&gt;&amp;nbsp;t&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;&lt;span&gt;Assembly&lt;/span&gt;.LoadFrom(assemblyFileName).GetTypes()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;where&lt;/span&gt;&amp;nbsp;levelMap.Keys.Contains(t.Namespace)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;group&lt;/span&gt;&amp;nbsp;t&amp;nbsp;&lt;span&gt;by&lt;/span&gt;&amp;nbsp;t.Namespace
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;into&lt;/span&gt;&amp;nbsp;g
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;orderby&lt;/span&gt;&amp;nbsp;levelMap[g.Key]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;select&lt;/span&gt;&amp;nbsp;g;
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;levelsWithClasses&amp;nbsp;=&amp;nbsp;groups.Count();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Assert&lt;/span&gt;.IsTrue(levelsWithClasses&amp;nbsp;&amp;gt;&amp;nbsp;1,&amp;nbsp;&lt;span&gt;&amp;quot;Need&amp;nbsp;more&amp;nbsp;than&amp;nbsp;two&amp;nbsp;layers&amp;nbsp;to&amp;nbsp;validate&amp;nbsp;relationships.&amp;quot;&lt;/span&gt;);
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;errors&amp;nbsp;=&amp;nbsp;&lt;span&gt;new&lt;/span&gt;&amp;nbsp;&lt;span&gt;List&lt;/span&gt;&amp;lt;&lt;span&gt;string&lt;/span&gt;&amp;gt;();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span&gt;var&lt;/span&gt;&amp;nbsp;g&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;groups){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;layer&amp;nbsp;=&amp;nbsp;levelMap[g.Key];
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;//&amp;nbsp;verify&amp;nbsp;this&amp;nbsp;level&amp;nbsp;only&amp;nbsp;accesses&amp;nbsp;things&amp;nbsp;from&amp;nbsp;the&amp;nbsp;adjacent&amp;nbsp;lower&amp;nbsp;layer&amp;nbsp;(or&amp;nbsp;layers)&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;offLimitSubsets&amp;nbsp;=&amp;nbsp;&lt;span&gt;from&lt;/span&gt;&amp;nbsp;g1&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;groups&amp;nbsp;&lt;span&gt;where&lt;/span&gt;&amp;nbsp;!&lt;span&gt;new&lt;/span&gt;[]&amp;nbsp;{layer&amp;nbsp;-&amp;nbsp;1,&amp;nbsp;layer}.Contains(levelMap[g1.Key])&amp;nbsp;&lt;span&gt;select&lt;/span&gt;&amp;nbsp;g1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;offLimitTypes&amp;nbsp;=&amp;nbsp;offLimitSubsets.SelectMany(x&amp;nbsp;=&amp;gt;&amp;nbsp;x).ToList();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span&gt;Type&lt;/span&gt;&amp;nbsp;t&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;g){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span&gt;MethodInfo&lt;/span&gt;&amp;nbsp;m&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;t.GetAllMethods()){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;var&lt;/span&gt;&amp;nbsp;methodBody&amp;nbsp;=&amp;nbsp;m.GetMethodBody();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;if&lt;/span&gt;&amp;nbsp;(methodBody&amp;nbsp;!=&amp;nbsp;&lt;span&gt;null&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span&gt;LocalVariableInfo&lt;/span&gt;&amp;nbsp;v&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;methodBody
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.LocalVariables
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Where(v&amp;nbsp;=&amp;gt;&amp;nbsp;offLimitTypes
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Contains(v.LocalType)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;string&lt;/span&gt;.Format(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;quot;Method&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{0}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;has&amp;nbsp;local&amp;nbsp;variable&amp;nbsp;of&amp;nbsp;type&amp;nbsp;&lt;/span&gt;&lt;span&gt;{1}&lt;/span&gt;&lt;span&gt;&amp;nbsp;from&amp;nbsp;a&amp;nbsp;layer&amp;nbsp;it&amp;nbsp;shouldn&amp;#39;t.&amp;quot;&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m.Name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v.LocalType.FullName));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span&gt;ParameterInfo&lt;/span&gt;&amp;nbsp;p&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;m
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.GetParameters()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Where(p&amp;nbsp;=&amp;gt;&amp;nbsp;offLimitTypes
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Contains(p.ParameterType)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;string&lt;/span&gt;.Format(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;quot;Method&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{0}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;parameter&amp;nbsp;&lt;/span&gt;&lt;span&gt;{2}&lt;/span&gt;&lt;span&gt;&amp;nbsp;uses&amp;nbsp;parameter&amp;nbsp;type&amp;nbsp;&lt;/span&gt;&lt;span&gt;{1}&lt;/span&gt;&lt;span&gt;&amp;nbsp;from&amp;nbsp;a&amp;nbsp;layer&amp;nbsp;it&amp;nbsp;shouldn&amp;#39;t.&amp;quot;&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m.Name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.ParameterType.FullName,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.Name));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;if&lt;/span&gt;&amp;nbsp;(offLimitTypes.Contains(m.ReturnType)){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;string&lt;/span&gt;.Format(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;quot;Method&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{0}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;uses&amp;nbsp;return&amp;nbsp;type&amp;nbsp;&lt;/span&gt;&lt;span&gt;{1}&lt;/span&gt;&lt;span&gt;&amp;nbsp;from&amp;nbsp;a&amp;nbsp;layer&amp;nbsp;it&amp;nbsp;shouldn&amp;#39;t.&amp;quot;&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m.Name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m.ReturnType.FullName));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;&amp;nbsp;(&lt;span&gt;PropertyInfo&lt;/span&gt;&amp;nbsp;p&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;t
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.GetAllProperties()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Where(p&amp;nbsp;=&amp;gt;&amp;nbsp;offLimitTypes.Contains(p.PropertyType)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;string&lt;/span&gt;.Format(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;quot;Type&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{0}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;has&amp;nbsp;a&amp;nbsp;property&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{1}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;of&amp;nbsp;type&amp;nbsp;&lt;/span&gt;&lt;span&gt;{2}&lt;/span&gt;&lt;span&gt;&amp;nbsp;from&amp;nbsp;a&amp;nbsp;layer&amp;nbsp;it&amp;nbsp;shouldn&amp;#39;t.&amp;quot;&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.FullName,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.Name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p.PropertyType.FullName));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;foreach&lt;/span&gt;(&lt;span&gt;FieldInfo&lt;/span&gt;&amp;nbsp;f&amp;nbsp;&lt;span&gt;in&lt;/span&gt;&amp;nbsp;t.GetAllFields().Where(f=&amp;gt;offLimitTypes.Contains(f.FieldType)))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors.Add(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;string&lt;/span&gt;.Format(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;&amp;quot;Type&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{0}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;has&amp;nbsp;a&amp;nbsp;field&amp;nbsp;\&amp;quot;&lt;/span&gt;&lt;span&gt;{1}&lt;/span&gt;&lt;span&gt;\&amp;quot;&amp;nbsp;of&amp;nbsp;type&amp;nbsp;&lt;/span&gt;&lt;span&gt;{2}&lt;/span&gt;&lt;span&gt;&amp;nbsp;from&amp;nbsp;a&amp;nbsp;layer&amp;nbsp;it&amp;nbsp;shouldn&amp;#39;t.&amp;quot;&lt;/span&gt;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;t.FullName,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f.Name,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f.FieldType.FullName));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;if&lt;/span&gt;&amp;nbsp;(errors.Count&amp;nbsp;&amp;gt;&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;Assert&lt;/span&gt;.Fail(&lt;span&gt;String&lt;/span&gt;.Join(&lt;span&gt;Environment&lt;/span&gt;.NewLine,&amp;nbsp;&lt;span&gt;new&lt;/span&gt;[]&amp;nbsp;{&lt;span&gt;&amp;quot;Layering&amp;nbsp;violation.&amp;quot;&lt;/span&gt;}.Concat(errors)));
}&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;This method groups types within a layer, then goes through any layers that layer shouldn&amp;rsquo;t have access to (i.e. any layer that isn&amp;rsquo;t the lower adjacent layer, or &amp;ldquo;layer &amp;ndash; 1, layer&amp;rdquo; where we create &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;offLimitSubsets&lt;/span&gt;).&amp;nbsp; For each type we look at return values, parameter values, fields, properties, and methods for any types they use.&amp;nbsp; If any of those types are one of the off limit types, we add an error to our error collection.&amp;nbsp; At the end, if there&amp;rsquo;s any errors we assert and format a nice message with all the violations.&lt;/p&gt;
&lt;p&gt;This is a helper method that you&amp;rsquo;d use somewhere (maybe a helper static class, within the existing test class, whatever).&lt;/p&gt;
&lt;p&gt;This uses some extension classes to make it a bit more readable, which are here:&lt;/p&gt;
&lt;pre style="line-height:normal;background:white;"&gt;&lt;span style="font-family:Consolas;"&gt;&lt;span style="font-size:12pt;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre&gt;&lt;span&gt;public&lt;/span&gt;&amp;nbsp;&lt;span&gt;static&lt;/span&gt;&amp;nbsp;&lt;span&gt;class&lt;/span&gt;&amp;nbsp;&lt;span&gt;TypeExceptions&lt;/span&gt;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;public&lt;/span&gt;&amp;nbsp;&lt;span&gt;static&lt;/span&gt;&amp;nbsp;&lt;span&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span&gt;MethodInfo&lt;/span&gt;&amp;gt;&amp;nbsp;GetAllMethods(&lt;span&gt;this&lt;/span&gt;&amp;nbsp;&lt;span&gt;Type&lt;/span&gt;&amp;nbsp;type)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;if&lt;/span&gt;&amp;nbsp;(type&amp;nbsp;==&amp;nbsp;&lt;span&gt;null&lt;/span&gt;)&amp;nbsp;&lt;span&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span&gt;new&lt;/span&gt;&amp;nbsp;&lt;span&gt;ArgumentNullException&lt;/span&gt;(&lt;span&gt;&amp;quot;type&amp;quot;&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;return&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type.GetMethods(&lt;span&gt;BindingFlags&lt;/span&gt;.Instance&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.NonPublic&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.Static&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.Public).Where(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m&amp;nbsp;=&amp;gt;&amp;nbsp;!m.GetCustomAttributes(&lt;span&gt;true&lt;/span&gt;).Any(a&amp;nbsp;=&amp;gt;&amp;nbsp;a&amp;nbsp;&lt;span&gt;is&lt;/span&gt;&amp;nbsp;&lt;span&gt;CompilerGeneratedAttribute&lt;/span&gt;));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;public&lt;/span&gt;&amp;nbsp;&lt;span&gt;static&lt;/span&gt;&amp;nbsp;&lt;span&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span&gt;FieldInfo&lt;/span&gt;&amp;gt;&amp;nbsp;GetAllFields(&lt;span&gt;this&lt;/span&gt;&amp;nbsp;&lt;span&gt;Type&lt;/span&gt;&amp;nbsp;type)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;if&lt;/span&gt;&amp;nbsp;(type&amp;nbsp;==&amp;nbsp;&lt;span&gt;null&lt;/span&gt;)&amp;nbsp;&lt;span&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span&gt;new&lt;/span&gt;&amp;nbsp;&lt;span&gt;ArgumentNullException&lt;/span&gt;(&lt;span&gt;&amp;quot;type&amp;quot;&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;return&lt;/span&gt;&amp;nbsp;type.GetFields(&lt;span&gt;BindingFlags&lt;/span&gt;.Instance&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.NonPublic&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.Static&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.Public)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.Where(f&amp;nbsp;=&amp;gt;&amp;nbsp;!f.GetCustomAttributes(&lt;span&gt;true&lt;/span&gt;).Any(a&amp;nbsp;=&amp;gt;&amp;nbsp;a&amp;nbsp;&lt;span&gt;is&lt;/span&gt;&amp;nbsp;&lt;span&gt;CompilerGeneratedAttribute&lt;/span&gt;));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;public&lt;/span&gt;&amp;nbsp;&lt;span&gt;static&lt;/span&gt;&amp;nbsp;&lt;span&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span&gt;PropertyInfo&lt;/span&gt;&amp;gt;&amp;nbsp;GetAllProperties(&lt;span&gt;this&lt;/span&gt;&amp;nbsp;&lt;span&gt;Type&lt;/span&gt;&amp;nbsp;type)&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;if&lt;/span&gt;&amp;nbsp;(type&amp;nbsp;==&amp;nbsp;&lt;span&gt;null&lt;/span&gt;)&amp;nbsp;&lt;span&gt;throw&lt;/span&gt;&amp;nbsp;&lt;span&gt;new&lt;/span&gt;&amp;nbsp;&lt;span&gt;ArgumentNullException&lt;/span&gt;(&lt;span&gt;&amp;quot;type&amp;quot;&lt;/span&gt;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span&gt;return&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type.GetProperties(&lt;span&gt;BindingFlags&lt;/span&gt;.Instance&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.NonPublic&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.Static&amp;nbsp;|&amp;nbsp;&lt;span&gt;BindingFlags&lt;/span&gt;.Public).Where
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(p&amp;nbsp;=&amp;gt;&amp;nbsp;!p.GetCustomAttributes(&lt;span&gt;true&lt;/span&gt;).Any(a&amp;nbsp;=&amp;gt;&amp;nbsp;a&amp;nbsp;&lt;span&gt;is&lt;/span&gt;&amp;nbsp;&lt;span&gt;CompilerGeneratedAttribute&lt;/span&gt;));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;/pre&gt;
&lt;p&gt;Because the compiler generates fields for auto properties and methods for properties, we want to filter out any compiler-generated stuff (what caused the compiler to generate the code will raise a violation) so we don&amp;rsquo;t get any duplicate violations (and violations the user can&amp;rsquo;t do anything about).&amp;nbsp; (which is what the call to &lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;GetCustomAttributes&lt;/span&gt; is doing)&lt;/p&gt;
&lt;p&gt;I wasn&amp;rsquo;t expecting this to be that long; so, in future blog entries I&amp;rsquo;ll try to detail some other unit tests that validate or verify specific infrastructural details.&amp;nbsp; If you have any specific details you&amp;rsquo;re interested in, leave a comment.&lt;/p&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/05/25/automated-testing-isn-t-just-for-business-logic.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1810302" 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/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Unit+Testing/default.aspx">Unit Testing</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/05/25/automated-testing-isn-t-just-for-business-logic.aspx</feedburner:origLink></item><item><title>Dispose Pattern and “Set large fields to null”</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/iyO50Ix1Yjc/dispose-pattern-and-set-large-fields-to-null.aspx</link><pubDate>Fri, 27 Apr 2012 02:25:12 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1809240</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>10</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1809240</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/04/26/dispose-pattern-and-set-large-fields-to-null.aspx#comments</comments><description>&lt;p&gt;I was involved in a short side discussion about “should” fields be set to null in the &lt;font face="Courier New"&gt;Dispose&lt;/font&gt; method(s).&amp;#160; I’m not sure what the impetus of the question was; but, if you read through the &lt;a href="http://bit.ly/I8Xf3R"&gt;dispose pattern MSDN documentation&lt;/a&gt; (in most versions I believe) there’s a comment &lt;span&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:8.4pt;" color="#008000"&gt;// Set large fields to null. &lt;/font&gt;&lt;/font&gt;&lt;/span&gt;in the implementation of the virtual &lt;font face="Courier New"&gt;Dispose&lt;/font&gt; method within the &lt;font face="Courier New"&gt;if(!disposed)&lt;/font&gt; block and after the &lt;font face="Courier New"&gt;if(disposing)&lt;/font&gt; block.&amp;#160; But, that’s the only reference to setting fields to null during dispose.&amp;#160; There’s nothing else that I’ve been able to find in MSDN with regard to setting fields to null.&lt;/p&gt;  &lt;p&gt;At face value, setting a field to null means that the referenced object is now unrooted from the class that owns the field and, if that was the last root of that reference, the Garbage Collector (GC) is now free to release the memory used by the object that was referenced by that field.&amp;#160; Although advanced, this seems all very academic because the amount of time between unrooting the reference and the return from &lt;font face="Courier New"&gt;Dispose&lt;/font&gt; (and thus the unrooting of the parent object) would seem like a very short amount of time.&amp;#160; Even if the amount of time between these two actions is small, setting a single field to null (i.e. a single assignment) seems like such a minor bit of code to provide no adverse affects.&amp;#160; The prevalent opinion seems to be that the GC “handles” this case and does what is best for you without setting the field to null.&lt;/p&gt;  &lt;p&gt;The GC is pretty smart.&amp;#160; There’s a lot of bright people who have worked on the GC over the years; and it improves every release of .NET.&amp;#160; But, that doesn’t answer the question; is there benefit to setting a field to null in the &lt;font face="Courier New"&gt;Dispose&lt;/font&gt; method?&amp;#160; Considering there isn’t much guidance on the topic; I’d though I’d set aside any faith I have in the GC and throw some science at the problem: take my theory, create some experiments, make observations, and collect some evidence.&lt;/p&gt;  &lt;p&gt;What I did was to create two classes, identical except that the &lt;font face="Courier New"&gt;Dispose&lt;/font&gt; method doesn’t set a reference field to null.&amp;#160; The classes contain an field that could reference a “large” or “small” object: I would experiment with large objects and small objects and observe the differences.&amp;#160; The following are the classes:&lt;/p&gt;  &lt;pre style="line-height:normal;background:white;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:7.8pt;"&gt;	&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size:7.8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;First&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;IDisposable&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size:7.8pt;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; {
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;[] arr = &lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;[&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Constants&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;.ArraySize];
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;[] GetArray() {
			&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; arr;
		}
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; Dispose() {
			arr = &lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;null&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;;
		}
	}
 
	&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Second&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; : &lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;IDisposable&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; {
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;[] arr = &lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;[&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Constants&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;.ArraySize];
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;[] GetArray() {
			&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:7.8pt;"&gt;&lt;font color="#000000"&gt; arr;
		}
 
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Dispose() {
		}
	}
&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;I would vary &lt;font face="Courier New"&gt;Constants.ArraySize&lt;/font&gt; constant to make the &lt;font face="Courier New"&gt;arr&lt;/font&gt; reference a “large” object or a “small” object.&amp;#160; I then created a loop that created several thousand instances of one of these classes then forced a garbage collection at the end; keeping track of the start time and the end time via &lt;font face="Courier New"&gt;Stopwatch&lt;/font&gt;:&lt;/p&gt;

&lt;pre style="line-height:normal;background:white;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;&lt;font style="font-size:7.8pt;"&gt;	&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size:7.8pt;"&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Program&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size:7.8pt;"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; {
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;const&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; Iterations = 10000;
 
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; Main(&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;[] args)
		{
			&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; stopwatch = &lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Stopwatch&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;.StartNew();
			&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;for&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; i = 0; i &amp;lt; Iterations; ++i)
			{
				&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; f = &lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;First&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;())
				{
					ConsumeValue(f.GetArray().Length);
				}
			}
			&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;GC&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;.Collect();
			stopwatch.Stop();
			&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Trace&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.WriteLine(&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;String&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Format(&lt;/font&gt;&lt;span&gt;&lt;font color="#a31515"&gt;&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#3cb371"&gt;{0}&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#3cb371"&gt;{1}&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;, stopwatch.Elapsed, stopwatch.ElapsedTicks));
			stopwatch = &lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Stopwatch&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;.StartNew();
			&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;for&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt; i = 0; i &amp;lt; Iterations; ++i)
			{
				&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;using&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; (&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;var&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; s = &lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;new&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Second&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;())
				{
					ConsumeValue(s.GetArray().Length);
				}
			}
			&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;GC&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000"&gt;.Collect();
			stopwatch.Stop();
			&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;Trace&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.WriteLine(&lt;/font&gt;&lt;span&gt;&lt;font color="#2b91af"&gt;String&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;.Format(&lt;/font&gt;&lt;span&gt;&lt;font color="#a31515"&gt;&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#3cb371"&gt;{0}&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;&amp;#160;&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#3cb371"&gt;{1}&lt;/font&gt;&lt;/span&gt;&lt;span&gt;&lt;font color="#a31515"&gt;&amp;quot;&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font style="font-size:7.8pt;"&gt;&lt;font color="#000000"&gt;, stopwatch.Elapsed, stopwatch.ElapsedTicks));
		}
 
		&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;static&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt;&amp;#160;&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; ConsumeValue(&lt;/font&gt;&lt;span&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;/span&gt;&lt;font color="#000000"&gt; x) {
		}
	}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;I wanted to make sure instanced got optimized away so the &lt;font face="Courier New"&gt;GetArray&lt;/font&gt; method makes sure the &lt;font face="Courier New"&gt;arr&lt;/font&gt; field sticks around and the &lt;font face="Courier New"&gt;ConsumeValue&lt;/font&gt; makes sure the &lt;font face="Courier New"&gt;First&lt;/font&gt;/&lt;font face="Courier New"&gt;Second&lt;/font&gt; instances stick around (more a knit-picker circumvention measure :).&amp;#160; Results are the 2nd result from running the application 2 times.&lt;/p&gt;

&lt;p&gt;As it turns out, the results were very interesting (at least to me :).&amp;#160; The results are as follows:&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 85000 Debug: yes Elapsed time: 00:00:00.0759408 Ticks: 170186.
  &lt;br /&gt;Iterations: 10000 ArraySize: 85000 Debug: yes Elapsed time: 00:00:00.7449450 Ticks: 1669448.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 85000 Debug: no Elapsed time: 00:00:00.0714526 Ticks: 160128.
  &lt;br /&gt;Iterations: 10000 ArraySize: 85000 Debug: no Elapsed time: 00:00:00.0753187 Ticks: 168792.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 1 Debug: yes Elapsed time: 00:00:00.0009410 Ticks: 2109.
  &lt;br /&gt;Iterations: 10000 ArraySize: 1 Debug: yes Elapsed time: 00:00:00.0007179 Ticks: 1609.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 1 Debug: no Elapsed time: 00:00:00.0005225 Ticks: 1171.
  &lt;br /&gt;Iterations: 10000 ArraySize: 1 Debug: no Elapsed time: 00:00:00.0003908 Ticks: 876.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 1000 Debug: yes Elapsed time: 00:00:00.0088454 Ticks: 19823.
  &lt;br /&gt;Iterations: 10000 ArraySize: 1000 Debug: yes Elapsed time: 00:00:00.0062082 Ticks: 13913.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 1000 Debug: no Elapsed time: 00:00:00.0096442 Ticks: 21613.
  &lt;br /&gt;Iterations: 10000 ArraySize: 1000 Debug: no Elapsed time: 00:00:00.0058977 Ticks: 13217.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 10000 Debug: yes Elapsed time: 00:00:00.0527439 Ticks: 118201.
  &lt;br /&gt;Iterations: 10000 ArraySize: 10000 Debug: yes Elapsed time: 00:00:00.0528719 Ticks: 118488.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 10000 Debug: no Elapsed time: 00:00:00.0478136 Ticks: 107152.
  &lt;br /&gt;Iterations: 10000 ArraySize: 10000 Debug: no Elapsed time: 00:00:00.0524012 Ticks: 117433.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 40000 Debug: yes Elapsed time: 00:00:00.0491652 Ticks: 110181.
  &lt;br /&gt;Iterations: 10000 ArraySize: 40000 Debug: yes Elapsed time: 00:00:00.3580011 Ticks: 802293.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 40000 Debug: no Elapsed time: 00:00:00.0467649 Ticks: 104802.
  &lt;br /&gt;Iterations: 10000 ArraySize: 40000 Debug: no Elapsed time: 00:00:00.0487685 Ticks: 109292.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 30000 Debug: yes Elapsed time: 00:00:00.0446106 Ticks: 99974.
  &lt;br /&gt;Iterations: 10000 ArraySize: 30000 Debug: yes Elapsed time: 00:00:00.2748007 Ticks: 615838.&lt;/p&gt;

&lt;p&gt;Iterations: 10000 ArraySize: 30000 Debug: no Elapsed time: 00:00:00.0411109 Ticks: 92131.
  &lt;br /&gt;Iterations: 10000 ArraySize: 30000 Debug: no Elapsed time: 00:00:00.0381225 Ticks: 85434.

  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;For the most part, results in debug mode are meaningless.&amp;#160; There’s no point in making design/coding decisions based on perceived benefits in debug mode; so, I don’t the results other than to document them above.&lt;/p&gt;

&lt;p&gt;The numbers could go either way, if we look at percentages; release mode, setting a field to null seems to be slower 50% of the time and faster 50% of the time.&amp;#160; When setting a field to null is faster it’s insignificantly faster (5.41%, 9.59%, and 4.28% faster) when it’s slower it’s insignificantly slower but more slow than it is fast (133.68%, 163.52%, and 107.84% slower).&amp;#160; Neither seems to make a whole lot of difference (like 10281 ticks over 10000 iterations in the biggest difference for about 1 tick per iteration—1000 byte array at 10000 iterations).&amp;#160; If we look at just the time values, we start to see that setting a field starts to approach being faster (when it’s slower it’s slower by 295, 8396, and 6697 ticks; when it’s faster it’s faster by 8664, 10281, 4490).&amp;#160; Oddly though, setting “large” fields to null isn’t the biggest of faster setting field to null values.&amp;#160; But, of course, I don’t know what the documentation means by “large”; it could be large-heap objects or some other arbitrary size.&lt;/p&gt;

&lt;p&gt;Of course there’s other variables that could affect things here that I haven’t accounted for (server GC, client GC, GC not occurring at specific time, better sample size, better sample range, etc.); so, take the results with a grain of salt.&lt;/p&gt;

&lt;p&gt;What should you do with this evidence?&amp;#160; It’s up to you.&amp;#160; I suggest not taking it as gospel and making a decision that is best for you own code based on experimentation and gathered metrics in the circumstances unique to your application and its usage..&amp;#160; i.e. setting a field to null in Dispose is neither bad nor good in the general case.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/04/26/dispose-pattern-and-set-large-fields-to-null.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1809240" 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/Pontification/default.aspx">Pontification</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/DevCenterPost/default.aspx">DevCenterPost</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/04/26/dispose-pattern-and-set-large-fields-to-null.aspx</feedburner:origLink></item><item><title>Software Design and First Principles–Part 0: Concepts of Object Orientation</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/R3j1-r9XhW8/software-design-and-first-principles-part-0-concepts-of-object-orientation.aspx</link><pubDate>Thu, 23 Feb 2012 16:06:17 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1806328</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1806328</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/02/23/software-design-and-first-principles-part-0-concepts-of-object-orientation.aspx#comments</comments><description>&lt;p&gt;I often compare software development with building houses or woodworking.&amp;#160; I sometimes even compare software development with the vocation of electrician.&amp;#160; In each of these other vocations, craftspeople need to go through a period of apprenticeship and mentoring before being “allowed” to practice their craft.&amp;#160; In each of these vocations there are a series of rules that apply to a lot of the basics of what what they do.&amp;#160; With building houses there are techniques and principles that are regulated by building codes; with electricians there’s techniques and fundamentals that are effectively regulated by electrical codes and standards.&amp;#160; It’s one thing to learn the techniques, principles, and fundamental laws of physics; but, it’s another thing to be able to call yourself an electrician or a carpenter.&lt;/p&gt;  &lt;p&gt;Now, don’t get me wrong; I’m not advocating that software development be a licensed trade—that’s an entirely different conversation.&amp;#160; But, I do believe that many of the techniques and principles around software development take a lot of mentorship in order to get right.&amp;#160; Just like electricity, they’re not the most intuitive of techniques and principles.&amp;#160; But, just like electricity, it’s really good to know why you’re doing something so you can know its limits an better judge “correctness” in different scenarios.&lt;/p&gt;  &lt;p&gt;To that effect, in order to understand many of the software development design techniques and patterns, I think the principles behind them are being ignored somewhat in a rush to get hands-on experience with certain techniques.&amp;#160; I think it’s important that we remember and understand what—I’m deeming—“first principles”.&lt;/p&gt;  &lt;p&gt;A &lt;strong&gt;First Principle&lt;/strong&gt; is a foundational principle about what it applies to.&amp;#160; Some of the principles I’m going to talk about may not all be foundational; but, I view then as almost as important as foundational, so I’m including them in First Principles.&lt;/p&gt;  &lt;p&gt;From an object-oriented standpoint, there’s lots of principles that we can apply.&amp;#160; Before I get too deeply into these principles, I think it’s useful to remind ourselves what object-orientation is.&amp;#160; I’m not going to get too deep into OO here; I’ll assume you’ve got some experience writing and designing object-oriented programs.&amp;#160; But, I want to associate the principles to the OO concepts that guide them; so, It’s important you as the reader are on the same page as me.&lt;/p&gt;  &lt;p&gt;OO really involves various concepts.&amp;#160; These concepts are typically outlined by: Encapsulation, abstraction, inheritance, Polymorphism (at least subtype, but usually parametric and ad-hoc as well), and “message passing”.&amp;#160; I’m going to ignore message passing in this part; other than to say this is typically implemented as method calls…&lt;/p&gt;  &lt;p&gt;You don’t have to use all the OO concepts when you’re using an OO language; but, you could argue that &lt;strong&gt;encapsulation&lt;/strong&gt; is one concept that is fundamental.&amp;#160; Encapsulation is sometimes referred to information hiding; but, I don’t think that term does it justice.&amp;#160; Sure, an object with private fields and methods “hides” information; but, the fact that it hides the privates of the type through a public interface of methods isn’t even alluded to in “information hiding”.&amp;#160; Encapsulation is, thus, a means to keep privates private and to provide a consistent public interface to act upon or access those privates.&amp;#160; The interface is an abstraction of the implementation details (the private data) of the class.&lt;/p&gt;  &lt;p&gt;The next biggest part of OO is &lt;strong&gt;abstraction&lt;/strong&gt;.&amp;#160; As we’ve seen, encapsulation is a form of abstraction (data abstraction); but the abstraction we’re focusing on now is one that decouples other implementation details.&amp;#160; Abstraction can be implemented with inheritance in many languages (e.g. code can know now to deal with a Shape, and not care that it’s given a Rectangle) and that inheritance can use abstract types. Some OO languages expand abstraction abilities to include things like interfaces—although you could technically do the same thing with an abstract type that had no implementation.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Inheritance&lt;/strong&gt; is key to many of other concepts in OO—abstraction, subtype polymorphism, interfaces, etc.&amp;#160; (if we view an interface as an abstract type with no code, then something that “implements” an interface is really just inheriting from an abstract type; but, my focus isn’t these semantics).&amp;#160; We often let our zeal to model artefacts in our design and run into problems with the degree and the depth of our inheritance; a point I hope to revisit in a future post in this series.&lt;/p&gt;  &lt;p&gt;Although you could technically use an OO language and not use polymorphism in any way, I think OO languages’ greatest features is polymorphism.&amp;#160; &lt;strong&gt;Subtype polymorphism&lt;/strong&gt;, as I’ve noted, is a form of abstraction (Shape, Rectangle…).&amp;#160; But all other types of polymorphism are also abstractions—they’re replacing something concrete (implementation details) with something less concrete (abstract).&amp;#160; With subtype polymorphism that abstraction is an abstract type or a base type; with &lt;strong&gt;parametric polymorphism&lt;/strong&gt; we generally create an algorithm abstraction that is decoupled from the data involved (Generics in .NET); and ad-hoc polymorphism is overloading—a decoupling of one particular method to one of many.&lt;/p&gt;  &lt;p&gt;I quickly realized the scope of this topic is fairly large and that one post on the topic would be too much like drinking from a firehose as well as potentially to be protracted (and risking never getting done at all :).&amp;#160; So, I’ve split up what I wanted to talk about into chunks.&amp;#160; I’m not entirely sure what the scope actually is yet; I’ll kind of figure that out as a I go or let feedback guide me.&amp;#160; Now that we’ve got most of the OO concepts in our head, the next post will begin detailing the principles I wanted to talk about.&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/02/23/software-design-and-first-principles-part-0-concepts-of-object-orientation.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1806328" 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+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><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Principles/default.aspx">Software Development Principles</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/02/23/software-design-and-first-principles-part-0-concepts-of-object-orientation.aspx</feedburner:origLink></item><item><title>The Flawed Eventually-upgrade Software Model</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/KpRvYwQiYNs/the-flawed-eventually-upgrade-software-model.aspx</link><pubDate>Mon, 13 Feb 2012 21:41:34 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1805957</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>5</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1805957</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/02/13/the-flawed-eventually-upgrade-software-model.aspx#comments</comments><description>&lt;p&gt;I think Windows XP was the first &lt;em&gt;real&lt;/em&gt; release of Windows--it had finally gotten to a usability and stability point that people could accept.&amp;#160; The &lt;a href="http://bit.ly/wHHmer"&gt;Microsoft support model&lt;/a&gt; changed shortly after Windows XP was released to basically support any piece of software for as long as ten years (if you paid extra for support roughly 2 years after a successive version was released). To paraphrase a famous law: &lt;em&gt;software becomes obsolete every 18 months&lt;/em&gt;.&amp;#160; That was true for a long time; but hardware and software isn&amp;#39;t improving at that rate any more.&amp;#160;&amp;#160; Software has basically caught up with existing hardware design and now has the capability of sustaining itself, without upgrade, for much longer than it did 10 years ago.&lt;/p&gt;  &lt;p&gt;To paraphrase once again: &lt;em&gt;you can make some of the people happier all of the time, but you can&amp;#39;t make all of the people happier all of the time&lt;/em&gt;.&amp;#160; Releasing new versions of software now-a-days is more about attempting to make more people happier than were happier before.&amp;#160; To approach your solution or your technology from a 100% buy-in point of view is unrealistic.&amp;#160; I think we&amp;#39;ve seen the fallout of that model for at least the last 10 years.&amp;#160; People have said that successors to software like Windows XP, on their own, aren&amp;#39;t enough to make people happier than they already are.&amp;#160; To try to force a change is only coming back with push-back.&amp;#160; The friction that once kept people on a particular brand of OS or even particular architecture is gone--people are exercising their options if they’re unable to use what they’re happy with.&lt;/p&gt;  &lt;p&gt;I think it’s time for software companies to change their model so customers can buy into an indefinite support model for software.&amp;#160; I think businesses are more than willing to &lt;strong&gt;spend more money&lt;/strong&gt; to get &lt;strong&gt;support&lt;/strong&gt; for some software packages longer &lt;strong&gt;than to buy the latest version every &lt;em&gt;x&lt;/em&gt; number of years&lt;/strong&gt;.&amp;#160; If you look at the TCO of upgrading away from XP compared to what a business pays Microsoft for the OS, it&amp;#39;s very much more. Companies are willing to offset that cost and buy support for XP rather than upgrade away from XP.&amp;#160; It just so happens that Microsoft extended support for XP rather than change their core model.&lt;/p&gt;  &lt;p&gt;I think a the current model effectively giving customers the choice between abandoning XP and going to the latest version of &lt;em&gt;an&lt;/em&gt; operating system (because you&amp;#39;re effectively forcing them to make that evaluation) the more likely that you end up forcing people away from Windows entirely.&amp;#160; People and businesses are re-evaluating whey they need their computers and thus the operating system installed on it.&amp;#160; There’s much more a need to consume data over the Internet than there was 10 years ago.&amp;#160; People and companies are recognizing that and they’re also recognizing there are many more options for doing just that.&lt;/p&gt;  &lt;p&gt;With this model, moving forward, innovation will drive software sales more than they do now.&amp;#160; People will upgrade not because it’s the latest version and not because they have to upgrade their hardware; but because the innovation of the software is pervasive enough to justify upgrading.&amp;#160; &lt;em&gt;Different&lt;/em&gt; wouldn’t be enough to sell upgrades.&lt;/p&gt;  &lt;p&gt;What do you think?&amp;#160; Do you think the eventually-upgrade software model is out of date?&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:4px 0px 4px 0px;"&gt;&lt;iframe src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/02/13/the-flawed-eventually-upgrade-software-model.aspx" scrolling="no" frameborder="0" style="border:none;width:325px;height:80px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="wlWriterHeaderFooter" style="margin:0px;padding:0px 0px 0px 0px;"&gt; &lt;script type="text/javascript"&gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&lt;/script&gt;&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1805957" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pontification/default.aspx">Pontification</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/02/13/the-flawed-eventually-upgrade-software-model.aspx</feedburner:origLink></item><item><title>The Rat-hole of Object-oriented Mapping</title><link>http://feedproxy.google.com/~r/PeterRitchiesMvpBlog/~3/39NAmVZBX_E/the-rat-hole-of-object-oriented-mapping.aspx</link><pubDate>Fri, 10 Feb 2012 17:56:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1805879</guid><dc:creator>PeterRitchie</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://msmvps.com/blogs/peterritchie/rsscomments.aspx?PostID=1805879</wfw:commentRss><comments>http://msmvps.com/blogs/peterritchie/archive/2012/02/10/the-rat-hole-of-object-oriented-mapping.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://bit.ly/waD5m6"&gt;Mark Seemann&lt;/a&gt; recently had a &lt;a href="http://bit.ly/xHRYMz"&gt;great post&lt;/a&gt; that, as most of his posts seem to do, challenges the average reader to re-think their reality a bit.&amp;nbsp; The post is titled &amp;ldquo;Is Layering Worth the Mapping&amp;rdquo;.&amp;nbsp; In the post Mark essentially details some of the grief and friction that developers face when they need to decouple two or more concepts by way of an abstraction.&lt;/p&gt;
&lt;p&gt;Mark takes the example of layering.&amp;nbsp; Layering is a one way coupling between two &amp;ldquo;layers&amp;rdquo; where the &amp;ldquo;higher-level&amp;rdquo; layer takes a dependency on abstractions in a &amp;ldquo;lower-level&amp;rdquo; layer.&amp;nbsp; Part of his example is a UI layer communicates with a domain layer about musical track information.&amp;nbsp; That track information that is communicated lives in a hand-crafted Track abstraction.&amp;nbsp; Typically this abstraction would live with the lower-level layer to maintain the unidirectional coupling.&amp;nbsp; Of course the UI layer needs a Track concretion for it to do its job and must map between the higher-level layer and the lower-level layer.&amp;nbsp; To further complicate things other decoupling may occur within each layer to manage dependencies.&amp;nbsp; The UI may implement an MVx pattern in which case there may be a specific &amp;ldquo;view-model&amp;rdquo; track abstraction, the data layer may employ object-relational mapping, etc. etc.&lt;/p&gt;
&lt;p&gt;Mark goes on to describe some &amp;ldquo;solutions&amp;rdquo; that often fall out of scenarios like this in a need to help manage the sheer magnitude of the classes involved: shared DTOs as cross-cutting entities, POCO classes, classes with only automatic properties, etc.&lt;/p&gt;
&lt;p&gt;It&amp;#39;s not just layering.&amp;nbsp; Layering lives in this grey area between in-memory modules and out-of-process &amp;quot;tiers&amp;quot;.&amp;nbsp; Layering, I think, is an attempt to get the benefits of out-of-process decoupling without the infrastructure concerns of connecting and communicating between out-of-process processes. Of course, over and above the module/assembly separation, the only thing enforcing this decoupling in layers is skill and being methodical.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m convinced layering is often, or often becomes, a &amp;quot;speculative generality&amp;quot; to give some &amp;quot;future proofing&amp;quot; to the application since layering so closely resembles &amp;quot;tiering&amp;quot; (not to be confused with the eventual response of &amp;quot;tearing&amp;quot;) as to make it easy to make it tiered should there ever be a need for it.&amp;nbsp; To be clear, this is the &lt;strong&gt;wrong&lt;/strong&gt; impetus to design a software solution.&amp;nbsp; You&amp;rsquo;re effectively setting yourself up to fail by essentially &amp;ldquo;making up&amp;rdquo; requirements that are more than likely going to be wrong.&amp;nbsp; If the requirements for the design are based on fallacies, they too are designed wrong.&amp;nbsp; But, you have to continue to maintain this design until you re-write it (ever noticed that anti-pattern?).&lt;/p&gt;
&lt;p&gt;But, implementing tiers or any sort of communication between processes often ends up in the same state.&amp;nbsp; You have internal &amp;quot;domain&amp;quot; entities within the processes (and even within logical boundaries within those processes) that end up spawning the need for &amp;quot;DTO&amp;quot; objects that live at the seams on one or either side of the communication.&amp;nbsp; Further that, many times that communication is facilitated by frameworks like WCF that create their own DTOs (SOAP envelopes for example).&amp;nbsp; Except you&amp;#39;re mandated by the physical boundaries of processes and you&amp;#39;re forced to do things like shared-type assemblies to model the cross-cutting &amp;quot;entities&amp;quot; (if you choose that cross-cutting &amp;quot;optimization&amp;rdquo;) introducing a whole new level of effort and a massive surface area for attracting human error (you&amp;#39;ve technically introduced the need for versioning, potentially serialization, deployment issues, etc. etc.).&lt;/p&gt;
&lt;p&gt;Creating an object-oriented type to simply act as a one-way container to something that lives on the other size of some logical or physical boundary has appeared to me to be a smell for quite a while.&amp;nbsp; e.g. the UI layer in Mark&amp;#39;s original example has this concept of a &amp;quot;Track&amp;quot; DTO-like type that when used is only used in one direction at a time.&amp;nbsp; When moving from the UI to the domain layer it&amp;#39;s only written to.&amp;nbsp; If it gets a &amp;quot;track&amp;quot; back from the domain layer the UI layer only reads from it.&amp;nbsp; Abstracting this into an OO class seems pointless and, as Mark says, not particularly beneficial.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look specifically at the in-memory representation of something like a &amp;ldquo;Track&amp;rdquo;.&amp;nbsp; We&amp;rsquo;ll limit our self and say that we need four Track abstractions: one for the view model, one for the domain layer abstraction, one for the data layer abstraction, and one for the object-relational mapping.&amp;nbsp; (I&amp;rsquo;ve assumed that the data layer may not have a track &amp;ldquo;entity&amp;rdquo; and is only responsible for pushing data around).&amp;nbsp; So, in effect we have four Track DTO classes in our system (and two or three Track &amp;ldquo;entities&amp;rdquo;).&amp;nbsp; But, if we look at the in-memory representation of instances of these objects they&amp;rsquo;re effectively identical&amp;mdash;each one can&amp;rsquo;t really have more data than another otherwise there&amp;rsquo;s something wrong.&amp;nbsp; If we look at what&amp;rsquo;s actually happing with this data, we&amp;rsquo;re really writing a lot of code to copy memory around in a really inefficient way.&amp;nbsp; The DTO classes in part become the way to copy memory.&amp;nbsp; To be fair, this is a side-effect of the fact we&amp;rsquo;re manually mapping from one abstraction to another or from one abstraction to an entity (or vice-versa).&lt;/p&gt;
&lt;p&gt;This type of thing isn&amp;rsquo;t entirely unknown; it sometimes goes by the name of &lt;strong&gt;ceremony&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For the most part, I think computer languages are hindering us in our ability to address this.&amp;nbsp; Languages in general tend to maintain this specific way of messaging called method-calling that limits our ability to communicate only information that can be encapsulated by the language&amp;#39;s or platform&amp;#39;s type-system.&amp;nbsp; But, to a certain extent we&amp;#39;re also hindered by our myopia of &amp;quot;everything must be a type in language X&amp;quot;.&amp;nbsp; Maybe this is another manifestation of Maslow&amp;#39;s Hammer.&lt;/p&gt;
&lt;p&gt;Imagine if you removed all the mapping code in a complex system&amp;mdash;especially a distributed system&amp;mdash;and were left with just the &amp;ldquo;domain&amp;rdquo; code.&amp;nbsp; I&amp;rsquo;ve done this with one system and I was astounded that over 75% of the code in the system had nothing to do with the systems &amp;ldquo;domain&amp;rdquo; (the &amp;ldquo;value-add&amp;rdquo;) and was &amp;ldquo;ceremony&amp;rdquo; to facilitate data mapping.&lt;/p&gt;
&lt;p&gt;I sometimes hear this isn&amp;rsquo;t so much of a problem with specific frameworks.&amp;nbsp; I&amp;rsquo;m often told that these frameworks do all the heavy lifting like this for us.&amp;nbsp; But, they really don&amp;rsquo;t.&amp;nbsp; The frameworks really just introduce another seam.&amp;nbsp; The issue of Impedance Mismatch isn&amp;rsquo;t just related to object-relational mapping.&amp;nbsp; I has to do with any mapping where both sides aren&amp;rsquo;t constrained by the same rules.&amp;nbsp; I&amp;rsquo;ve blogged about this before. but I can use some &amp;ldquo;data framework&amp;rdquo; to generate &amp;ldquo;entities&amp;rdquo; based on a data model or even based on POCO&amp;rsquo;s.&amp;nbsp; Some view this as solving the problem; but it doesn&amp;rsquo;t.&amp;nbsp; Each side operates under different rules.&amp;nbsp; The generated classes can only have as much impedance as what it has to communicate with, and you have to plan that that&amp;rsquo;s different than the impedance you&amp;rsquo;ll end up mapping from/to.&amp;nbsp; The only real solution to this is to introduce &lt;strong&gt;another DTO&lt;/strong&gt; to map between your domain and the classes generated by the framework so you are decoupled from the eventual &amp;ldquo;gotchas&amp;rdquo; where your domain has different expectations or rules than the framework you&amp;rsquo;re communicating with.&amp;nbsp; When people don&amp;rsquo;t do this, you see all sorts of complains like &amp;ldquo;date/time in X isn&amp;rsquo;t the same as what I need&amp;rdquo;, etc.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t fall into this rut.&amp;nbsp; Think about what you&amp;rsquo;re doing; if you&amp;rsquo;re got 4 DTOs to hold the same data; maybe there&amp;rsquo;s a better way of doing it.&amp;nbsp; Try to come up with something better and blog about it or at least talk about the problem out in the open like Mark.&lt;/p&gt;
&lt;div style="margin:0px;padding:4px 0px 4px 0px;" class="wlWriterHeaderFooter"&gt;&lt;iframe style="border:none;width:325px;height:80px;" frameborder="0" scrolling="no" src="http://www.facebook.com/widgets/like.php?href=http://msmvps.com/blogs/peterritchie/archive/2012/02/10/the-rat-hole-of-object-oriented-mapping.aspx"&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;div style="margin:0px;padding:0px 0px 0px 0px;" class="wlWriterHeaderFooter"&gt;
&lt;script type="text/javascript"&gt;&lt;/script&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1805879" 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/Design_2F00_Coding+Guidance/default.aspx">Design/Coding Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Pontification/default.aspx">Pontification</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Patterns/default.aspx">Patterns</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Software+Development+Guidance/default.aspx">Software Development Guidance</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Code+Smells/default.aspx">Code Smells</category><category domain="http://msmvps.com/blogs/peterritchie/archive/tags/Architecture/default.aspx">Architecture</category><feedburner:origLink>http://msmvps.com/blogs/peterritchie/archive/2012/02/10/the-rat-hole-of-object-oriented-mapping.aspx</feedburner:origLink></item></channel></rss>
