<?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>Jon Skeet: Coding Blog</title><link>http://msmvps.com/blogs/jon_skeet/default.aspx</link><description>C#, .NET, Java, software development etc
**This is my personal blog. The views expressed on these pages are mine alone and not those of my employer.**</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/JonSkeetCodingBlog" /><feedburner:info uri="jonskeetcodingblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>The perils of conditional mutability</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/BISytg6yMcs/the-perils-of-conditional-mutability.aspx</link><pubDate>Sun, 06 May 2012 13:58:45 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1809562</guid><dc:creator>skeet</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1809562</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1809562</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/05/06/the-perils-of-conditional-mutability.aspx#comments</comments><description>&lt;p&gt;This morning I was wrestling with trying to make some Noda Time unit tests faster. For some reason, the &lt;a href="http://teamcity.codebetter.com"&gt;continuous integration host we&amp;#39;re using&lt;/a&gt; is &lt;em&gt;really&lt;/em&gt; slow at loading resources under .NET 4. The unit tests which run in 10 seconds on my home laptop take over three &lt;em&gt;hours&lt;/em&gt; on the continuous integration system. Taking stack traces at regular intervals showed the problem was with the NodaFormatInfo constructor, which reads some resources.&lt;/p&gt;  &lt;p&gt;I may look into streamlining the resource access later, but before we get to that point, I wanted to try to reduce the number of times we call that constructor in the first place. NodaFormatInfo is meant to be cached, so I wouldn&amp;#39;t have expected thousands of instances to be created - but it&amp;#39;s only cached when the System.Globalization.CultureInfo it&amp;#39;s based on is read-only. This is where the problems start...&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx"&gt;CultureInfo&lt;/a&gt; is &lt;em&gt;conditionally mutable &lt;/em&gt;(not an official term, just one I&amp;#39;ve coined for the purposes of this post). You can ask whether or not it&amp;#39;s read-only with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.isreadonly.aspx"&gt;IsReadOnly property&lt;/a&gt;, and obviously if it&amp;#39;s read-only you can&amp;#39;t change it. Additionally, CultureInfo is composed of other conditionally mutable objects - &lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx"&gt;DateTimeFormatInfo&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.aspx"&gt;NumberFormatInfo&lt;/a&gt; etc. There&amp;#39;s a static &lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.readonly.aspx"&gt;ReadOnly method&lt;/a&gt; on CultureInfo to create a read-only wrapper around a mutable CultureInfo. It&amp;#39;s not clearly documented whether that&amp;#39;s &lt;em&gt;expected&lt;/em&gt; to take a deep copy (so that callers can really rely on it not changing) or whether it&amp;#39;s expected to reflect any further changes made to the culture info it&amp;#39;s based on. To go in the other direction, you can call Clone on a CultureInfo to create a mutable copy of any existing culture.&lt;/p&gt;  &lt;p&gt;Further complications are introduced by the properties on the composite objects - we have properties such as &lt;a href="http://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.monthnames.aspx"&gt;DateTimeFormatInfo.MonthNames&lt;/a&gt; which returns a string array. Remember, arrays are &lt;em&gt;always&lt;/em&gt; mutable. So it&amp;#39;s really important to know whether the array reference returned from the property refers to a &lt;em&gt;copy&lt;/em&gt; of the underlying data, or whether it refers to the array that&amp;#39;s used internally by the type. Obviously for read-only DateTimeFormatInfo objects, I&amp;#39;d expect a copy to be returned - but for a mutable DateTimeFormatInfo, it would potentially make sense to return the underlying array reference. Unfortunately, the documentation doesn&amp;#39;t make this clear - but in practice, it always returns a copy. If you need to change the month names, you need to clone the array, mutate the clone, and then set the MonthNames property.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;All of this makes CultureInfo hard to work with&lt;/em&gt;. The caching decision earlier on only really works if a &amp;quot;read-only&amp;quot; culture genuinely won&amp;#39;t change behind the scenes. The type system gives you no help to catch subtle bugs at compile-time. Making any of this robust but efficient (in terms of taking minimal copies) is tricky to say the least.&lt;/p&gt;  &lt;p&gt;Not only does it make it hard to work with from a client&amp;#39;s point of view, but apparently it&amp;#39;s hard to implement correctly too...&lt;/p&gt;  &lt;h2&gt;First bug: Mono&amp;#39;s invariant culture isn&amp;#39;t terribly invariant...&lt;/h2&gt;  &lt;p&gt;(Broken in 2.10.8; apparently fixed later.)&lt;/p&gt;  &lt;p&gt;I discovered this while getting Noda Time&amp;#39;s unit tests to pass on Mono. Unfortunately there are some I&amp;#39;ve had to effectively disable at the moment, due to deficiencies in Mono (some of which are being fixed, of course).&lt;/p&gt;  &lt;p&gt;Here&amp;#39;s a program which builds a clone of the invariant culture, changes the &lt;em&gt;clone&amp;#39;s&lt;/em&gt; genitive month names, and then prints out the first &lt;em&gt;non-genitive&lt;/em&gt; name from the plain invariant culture:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;     &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Globalization;     &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CultureInfo clone = (CultureInfo) CultureInfo.InvariantCulture.Clone();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Note: not even deliberately changing MonthNames for this culture!&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clone.DateTimeFormat.MonthGenitiveNames[0] = &lt;span class="String"&gt;&amp;quot;Changed&amp;quot;&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Prints Changed&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(CultureInfo.InvariantCulture.DateTimeFormat.MonthNames[0]);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;I believe this bug is &lt;em&gt;really&lt;/em&gt; due to the lack of support for genitive month names in Mono at the moment - the MonthGenitiveNames property always just returns a reference to the month names for the invariant culture - without taking a copy first. (It always returns the invariant culture&amp;#39;s month names, even if you&amp;#39;re using a different culture entirely.) The code above shows an &amp;quot;innocent&amp;quot; attempt to change a mutable clone - but in reality we could have used &lt;em&gt;any&lt;/em&gt; culture (including an immutable one) to make the change.&lt;/p&gt;  &lt;p&gt;Note that in the .NET implementation, the change would only have been to a copy of the underlying data, so even the &lt;em&gt;clone&lt;/em&gt; wouldn&amp;#39;t have reflected change anywhere.&lt;/p&gt;  &lt;h2&gt;Second bug: ReadOnly losing changes&lt;/h2&gt;  &lt;p&gt;The second bug is the one I found this morning. It looks like it&amp;#39;s fixed in .NET 4, but it&amp;#39;s present in .NET 3.5, which is where it bit me this morning. When you try to make a read-only wrapper around a mutated culture, some of the properties are preserved... but some aren&amp;#39;t:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;    &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Globalization;    &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CultureInfo clone = (CultureInfo) CultureInfo.InvariantCulture.Clone();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clone.DateTimeFormat.AMDesignator = &lt;span class="String"&gt;&amp;quot;ChangedAm&amp;quot;&lt;/span&gt;;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// The array is recreated on each call to MonthNames, so changing the&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// value within the array itself doesn&amp;#39;t work :(&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt;[] months = (&lt;span class="ReferenceType"&gt;string&lt;/span&gt;[]) clone.DateTimeFormat.MonthNames;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; months[0] = &lt;span class="String"&gt;&amp;quot;ChangedMonth&amp;quot;&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; clone.DateTimeFormat.MonthNames = months;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CultureInfo readOnlyCopy = CultureInfo.ReadOnly(clone);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(clone.DateTimeFormat.AMDesignator); &lt;span class="InlineComment"&gt;// ChangedAm&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(clone.DateTimeFormat.MonthNames[0]); &lt;span class="InlineComment"&gt;// ChangedMonth&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(readOnlyCopy.DateTimeFormat.AMDesignator); &lt;span class="InlineComment"&gt;// ChangedAm&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(readOnlyCopy.DateTimeFormat.MonthNames[0]); &lt;span class="InlineComment"&gt;// January (!)&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;I don&amp;#39;t know what&amp;#39;s going on here. In the end I just left the test code using the mutable clone, having added a comment explaining &lt;em&gt;why&lt;/em&gt; it wasn&amp;#39;t created a read-only wrapper.&lt;/p&gt;  &lt;p&gt;I&amp;#39;ve experimented with a few different options here, including setting the MonthNames property on the clone &lt;em&gt;after&lt;/em&gt; creating the wrapper. No joy - I simply can&amp;#39;t make the new month names stick in the read-only copy. &amp;lt;sigh&amp;gt;&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;I&amp;#39;ve been frustrated by the approach we&amp;#39;ve taken to cultures in Noda Time for a while. I haven&amp;#39;t worked out exactly what we should do about it yet, so it&amp;#39;s likely to stay somewhat annoying for v1, but I may well revisit it significantly for v2. Unfortunately, there&amp;#39;s nothing I can do about CultureInfo itself.&lt;/p&gt;  &lt;p&gt;What I would have &lt;em&gt;preferred&lt;/em&gt; in all of this is the builder pattern: make CultureInfo, DateTimeFormatInfo etc all immutable, but give each of them mutable builder types, with the ability to create a mutable builder based on an existing immutable instance, and obviously to create a new immutable instance from a builder. That would make all kinds of things simpler - including caching.&lt;/p&gt;  &lt;p&gt;For the moment though, I hope we can all learn lessons from this - or have old lessons reinforced, at least:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Making a single type behave in different ways based on different &amp;quot;modes&amp;quot; makes it hard to use correctly. (Yes, this is the same first conclusion as with DateTime in the previous post. Funny, that.)&lt;/li&gt;    &lt;li&gt;Immutability has to be deep to be meaningful: it&amp;#39;s not much use having a supposedly read-only object which composes a StringBuilder...&lt;/li&gt;    &lt;li&gt;Arrays should be &lt;a href="http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx"&gt;considered somewhat harmful&lt;/a&gt;. If you&amp;#39;re going to return an array from a method, make sure you document whether this is a &lt;em&gt;copy&lt;/em&gt; of the underlying data, or a &amp;quot;live&amp;quot; reference. (The latter should be very rare, particularly for a public API.) The exception here is if you return an empty array - that&amp;#39;s effectively immutable, so you can always return it with no problems.&lt;/li&gt;    &lt;li&gt;The builder pattern rocks - use it!&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In my next post I&amp;#39;ll try to get back to the TimeZoneInfo oddities I mentioned last time.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1809562" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/BISytg6yMcs" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Design/default.aspx">Design</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/05/06/the-perils-of-conditional-mutability.aspx</feedburner:origLink></item><item><title>More fun with DateTime</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/tSO4uPGTVe4/more-fun-with-datetime.aspx</link><pubDate>Wed, 02 May 2012 20:12:43 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1809416</guid><dc:creator>skeet</dc:creator><slash:comments>17</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1809416</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1809416</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/05/02/more-fun-with-datetime.aspx#comments</comments><description>&lt;p&gt;(Note that this is deliberately not posted in the &lt;a href="http://noda-time.blogspot.com/"&gt;Noda Time blog&lt;/a&gt;. I reckon it&amp;#39;s of wider interest from a design perspective, and I won&amp;#39;t be posting any of the equivalent &lt;a href="http://noda-time.googlecode.com"&gt;Noda Time&lt;/a&gt; code. I&amp;#39;ll just say now that we don&amp;#39;t have this sort of craziness in Noda Time, and leave it at that...)&lt;/p&gt;  &lt;p&gt;A few weeks ago, I was answering a Stack Overflow question when I noticed an operation around dates and times which &lt;em&gt;should&lt;/em&gt; have been losing information apparently not doing so. I investigated further, and discovered some &amp;quot;interesting&amp;quot; aspects of both DateTime and TimeZoneInfo. In an effort to keep this post down to a readable length (at least for most readers; certain WebDriver developers who shall remain nameless have probably given up by now already) I&amp;#39;ll save the TimeZoneInfo bits for another post.&lt;/p&gt;  &lt;h2&gt;Background: daylight saving transitions and ambiguous times&lt;/h2&gt;  &lt;p&gt;There&amp;#39;s one piece of &lt;em&gt;inherent&lt;/em&gt; date/time complexity you&amp;#39;ll need to understand for this post to make sense: sometimes, a local date/time occurs twice. For the purposes of this post, I&amp;#39;m going to assume you&amp;#39;re in the UK time zone. On October 28th 2012, at 2am local time (1am UTC), UK clocks will go back to 1am local time. So 1:20am local time occurs twice - once at 12:20am UTC (in daylight saving time, BST), and once at 1:20am UTC (in standard time, GMT).&lt;/p&gt;  &lt;p&gt;If you want to run any of the code in this post and you&amp;#39;re &lt;em&gt;not&lt;/em&gt; in the UK, please adjust the dates and times used to a similar ambiguity for when your clocks go back. If you happen to be in a time zone which doesn&amp;#39;t observe daylight savings, I&amp;#39;m afraid you&amp;#39;ll have to adjust your system time zone in order to see the effect for yourself.&lt;/p&gt;  &lt;h2&gt;DateTime.Kind and conversions&lt;/h2&gt;  &lt;p&gt;As you may already know, as of .NET 2.0, DateTime has a &lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.kind.aspx"&gt;Kind&lt;/a&gt; property, of type &lt;a href="http://msdn.microsoft.com/en-us/library/shx7s921.aspx"&gt;DateTimeKind&lt;/a&gt; - an enum with the following values:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Local: The DateTime is considered to be in the &lt;em&gt;system time zone&lt;/em&gt;. Not an arbitrary &amp;quot;local time in some time zone&amp;quot;, but in the specific current system time zone. &lt;/li&gt;    &lt;li&gt;Utc: The DateTime is considered to be in UTC (corollary: it always unambiguously represents an instant in time) &lt;/li&gt;    &lt;li&gt;Unspecified: This means different things in different contexts, but it&amp;#39;s a sort of &amp;quot;don&amp;#39;t know&amp;quot; kind; this is closer to &amp;quot;local time in some time zone&amp;quot; which is represented as LocalDateTime in Noda Time. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;DateTime provides three methods to convert between the kinds:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.touniversaltime.aspx"&gt;ToUniversalTime&lt;/a&gt;: if the original kind is Local or Unspecified, convert it from local time to universal time in the system time zone. If the original kind is Utc, this is a no-op. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx"&gt;ToLocalTime&lt;/a&gt;: if the original kind is Utc or Unspecified, convert it from UTC to local time. If the original kind is Local, this is a no-op. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.datetime.specifykind.aspx"&gt;SpecifyKind&lt;/a&gt;: keep the existing date/time, but &lt;em&gt;just&lt;/em&gt; change the kind. (So 7am stays as 7am, but it changes the &lt;em&gt;meaning&lt;/em&gt; of that 7am effectively.) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(Prior to .NET 2.0, ToUniversalTime and ToLocalTime were already present, but always &lt;em&gt;assumed&lt;/em&gt; the original value needed conversion - so if you called x.ToLocalTime().ToLocalTime().ToLocalTime() the result would probably end up with the appropriate offset from UTC being applied three times!)&lt;/p&gt;  &lt;p&gt;Of course, none of these methods change the existing value - DateTime is immutable, and a value type - instead, they return a &lt;em&gt;new&lt;/em&gt; value.&lt;/p&gt;  &lt;h2&gt;DateTime&amp;#39;s Deep Dark Secret&lt;/h2&gt;  &lt;p&gt;(The code in this section is presented in several chunks, but it forms a single complete piece of code - later chunks refer to variables in earlier chunks. Put it all together in a Main method to run it.)&lt;/p&gt;  &lt;p&gt;Armed with the information in the previous sections, we should be able to make DateTime lose data. If we start with 12:20am UTC and 1:20am UTC on October 28th as DateTimes with a kind of Utc, when we convert them to local time (on a system in the UK time zone) we should get 1:20am in both cases due to the daylight saving transition. Indeed, that works:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Start with different UTC values around a DST transition&lt;/span&gt;     &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; original1 = &lt;span class="Keyword"&gt;new&lt;/span&gt; DateTime(2012, 10, 28, 0, 20, 0, DateTimeKind.Utc);     &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; original2 = &lt;span class="Keyword"&gt;new&lt;/span&gt; DateTime(2012, 10, 28, 1, 20, 0, DateTimeKind.Utc);     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Convert to local time&lt;/span&gt;     &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; local1 = original1.ToLocalTime();     &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; local2 = original2.ToLocalTime();     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Result is the same for both values. Information loss?&lt;/span&gt;     &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; expected = &lt;span class="Keyword"&gt;new&lt;/span&gt; DateTime(2012, 10, 28, 1, 20, 0, DateTimeKind.Local);     &lt;br /&gt;Console.WriteLine(local1 == expected); &lt;span class="InlineComment"&gt;// True&lt;/span&gt;     &lt;br /&gt;Console.WriteLine(local2 == expected); &lt;span class="InlineComment"&gt;// True&lt;/span&gt;     &lt;br /&gt;Console.WriteLine(local1 == local2);&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// True&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;If we&amp;#39;ve started with two &lt;em&gt;different&lt;/em&gt; values, applied the same operation to both, and ended up with equal values, then we must have lost information, right? That doesn&amp;#39;t mean that operation is &amp;quot;bad&amp;quot; any more than &amp;quot;dividing by 2&amp;quot; is bad. You ought to be aware of that information loss, that&amp;#39;s all.&lt;/p&gt;  &lt;p&gt;So, we ought to be able to demonstrate that information loss further by converting back from local time to universal time. Here we have the opposite problem: from our local time of 1:20am, we have &lt;em&gt;two&lt;/em&gt; valid universal times we could convert to - either 12:20am UTC or 1:20am UTC. Both answers would be correct - they are universal times at which the local time would be 1:20am. So which one will get picked? Well... here&amp;#39;s the surprising bit:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Convert back to UTC &lt;/span&gt;    &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; roundTrip1 = local1.ToUniversalTime();&amp;#160; &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; roundTrip2 = local2.ToUniversalTime();     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Values round-trip correctly! Information has been recovered... &lt;/span&gt;    &lt;br /&gt;Console.WriteLine(roundTrip1 == original1);&amp;#160; &lt;span class="InlineComment"&gt;// True &lt;/span&gt;    &lt;br /&gt;Console.WriteLine(roundTrip2 == original2);&amp;#160; &lt;span class="InlineComment"&gt;// True &lt;/span&gt;    &lt;br /&gt;Console.WriteLine(roundTrip1 == roundTrip2); &lt;span class="InlineComment"&gt;// False&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;Somehow, each of the local values &lt;em&gt;knows&lt;/em&gt; which universal value it came from. The The information has been recovered, so the reverse conversion round-trips each value back to its original one. How is that possible?&lt;/p&gt;  &lt;p&gt;It turns out that DateTime actually has &lt;em&gt;four&lt;/em&gt; potential kinds: Local, Utc, Unspecified, and &amp;quot;local but treat it as the earlier option when resolving ambiguity&amp;quot;. A DateTime is really just a 64-bit number of ticks, but because the range of DateTime is only January 1st 0001 to December 31st 9999. That range can be represented in 62 bits, leaving 2 bits &amp;quot;spare&amp;quot; to represent the kind. 2 bits gives 4 possible values... the three documented ones and the shadowy extra one.&lt;/p&gt;  &lt;p&gt;Through experimentation, I&amp;#39;ve discovered that the kind is preserved if you perform arithmetic on the value, too... so if you go to another &amp;quot;fall back&amp;quot; DST transition such as October 30th 2011, the ambiguity resolution works the same way as before:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; local3 = local1.AddYears(-1).AddDays(2);&amp;#160; &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; local4 = local2.AddYears(-1).AddDays(2);&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;Console.WriteLine(local3.ToUniversalTime().Hour); &lt;span class="InlineComment"&gt;// 0 &lt;/span&gt;    &lt;br /&gt;Console.WriteLine(local4.ToUniversalTime().Hour); &lt;span class="InlineComment"&gt;// 1&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;If you use DateTime.SpecifyKind with DateTimeKind.Local, however, it goes back to the &amp;quot;normal&amp;quot; kind, even though it &lt;em&gt;looks&lt;/em&gt; like it should be a no-op:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Should be a no-op? &lt;/span&gt;    &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; local5 = DateTime.SpecifyKind(local1, local1.Kind);&amp;#160; &lt;br /&gt;Console.WriteLine(local5.ToUniversalTime().Hour); &lt;span class="InlineComment"&gt;// 1&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;Is this correct behaviour? Or should it be a no-op, just like calling ToLocalTime on a &amp;quot;local&amp;quot; DateTime is? (Yes, I&amp;#39;ve checked - that doesn&amp;#39;t lose the information.) It&amp;#39;s hard to say, really, as this whole business appears to be undocumented... at least, I haven&amp;#39;t seen anything in MSDN about it. (Please add a link in the comments if you find something. The behaviour actually goes against what&amp;#39;s documented, as far as I can tell.)&lt;/p&gt;  &lt;p&gt;I haven&amp;#39;t looked into whether various forms of serialization preserve values like this faithfully, by the way - but you&amp;#39;d have to work hard to reproduce it in non-framework code. You can&amp;#39;t explicitly construct a DateTime with the &amp;quot;extra&amp;quot; kind; the only ways I know of to create such a value are via a conversion to local time or through arithmetic on a value which already has the kind. (Admittedly if you&amp;#39;re serializing a DateTime with a Kind of Local, you&amp;#39;re already on potentially shaky ground, given that you could be deserializing it on a machine with a different system time zone.)&lt;/p&gt;  &lt;h2&gt;Unkind comparisons&lt;/h2&gt;  &lt;p&gt;I&amp;#39;ve misled you a little, I have to admit. In the code above, when I compared the &amp;quot;expected&amp;quot; value with the results of the first conversions, I deliberately specified DateTimeKind.Local in the constructor call. After all, that&amp;#39;s the kind we &lt;em&gt;do&lt;/em&gt; expect. Well, yes - but I then printed the result of comparing this value with local1 and local2... and those comparisons would have been the same regardless of the kind I&amp;#39;d specified in the constructor.&lt;/p&gt;  &lt;p&gt;All comparisons between DateTimes ignore the Kind property. It&amp;#39;s not just restricted to equality. So for example, consider this comparison:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// In June: Local time is UTC+1, so 8am UTC is 9am local &lt;/span&gt;    &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; dt1 = &lt;span class="Keyword"&gt;new&lt;/span&gt; DateTime(2012, 6, 1, 8, 0, 0, DateTimeKind.Utc);&amp;#160; &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; dt2 = &lt;span class="Keyword"&gt;new&lt;/span&gt; DateTime(2012, 6, 1, 8, 30, 0, DateTimeKind.Local);&amp;#160; &lt;br /&gt;Console.WriteLine(dt1 &amp;lt; dt2); &lt;span class="InlineComment"&gt;// True&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;When viewed in terms of &amp;quot;what instants in time do these both represent?&amp;quot; the answer here is wrong - when you convert both values into the same time zone (in either direction), dt1 occurs &lt;em&gt;after&lt;/em&gt; dt2. But a simple look at the properties tells a different story. In practice, I suspect that most comparisons between DateTime values of different kinds involve code which is at best sloppy and is quite possibly broken in a meaningful way.&lt;/p&gt;  &lt;p&gt;Of course, if you bring Kind=Unspecified into the picture, it becomes impossible to compare meaningfully in a kind-sensitive way. Is 12am UTC before or after 1am Unspecified? It depends what time zone you later use.&lt;/p&gt;  &lt;p&gt;To be clear, it &lt;em&gt;is&lt;/em&gt; a hard-to-resolve issue, and one that we don&amp;#39;t do terribly well at in Noda Time at the moment for ZonedDateTime. (And even with just LocalDateTime you&amp;#39;ve got issues between calendars.) This is a situation where providing separate Comparer&amp;lt;T&amp;gt; implementations works nicely - so you can explicitly say what kind of comparison you want.&lt;/p&gt;  &lt;h2&gt;Conclusions&lt;/h2&gt;  &lt;p&gt;There&amp;#39;s more fun to be had with a similar situation when we look at TimeZoneInfo, but for now, a few lessons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Giving a type different &amp;quot;modes&amp;quot; which make it mean fairly significantly different things is likely to cause headaches &lt;/li&gt;    &lt;li&gt;Keeping one of those modes secret (and preventing users from even constructing a value in that mode directly) leads to even more fun and games &lt;/li&gt;    &lt;li&gt;If two instances of your type are considered &amp;quot;equal&amp;quot; but behave differently, you should at least consider whether there&amp;#39;s something smelly going on &lt;/li&gt;    &lt;li&gt;There&amp;#39;s &lt;em&gt;always&lt;/em&gt; more fun to be had with DateTime... &lt;/li&gt; &lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1809416" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/tSO4uPGTVe4" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/05/02/more-fun-with-datetime.aspx</feedburner:origLink></item><item><title>Type initializer circular dependencies</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/aF_dVyhKyCg/type-initializer-circular-dependencies.aspx</link><pubDate>Sat, 07 Apr 2012 09:35:45 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1808561</guid><dc:creator>skeet</dc:creator><slash:comments>25</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1808561</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1808561</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/04/07/type-initializer-circular-dependencies.aspx#comments</comments><description>&lt;p&gt;To some readers, the title of this post may induce nightmarish recollections of late-night debugging sessions. To others it may be simply the epitome of jargon. Just to break the jargon down a bit:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Type initializer: the code executed to initialize the static variables of a class, and the static constructor &lt;/li&gt;    &lt;li&gt;Circular dependency: two bits of code which depend on each other - in this case, two classes whose type initializers each require that the other class is initialized &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;A quick example of the kind of problem I&amp;#39;m talking about would be helpful here. What would you expect this code to print?&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;     &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test     &lt;br /&gt;{&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(First.Beta);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; First     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Alpha = 5;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Beta = Second.Gamma;     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Second     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; Gamma = First.Alpha;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Of course, without even glancing at the specification, any expectations are pretty irrelevant. Here&amp;#39;s what the spec (section 10.5.5.1 of the C# 4 version):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration. If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;In addition to the language specification, the CLI specification gives more details about type initialization in the face of circular dependencies and multiple threads. I won&amp;#39;t post the details here, but the gist of it is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Type initialization acts like a lock, to prevent more than one thread from initializing a type &lt;/li&gt;    &lt;li&gt;If the CLI notices that type A needs to be initialized in order to make progress, but it&amp;#39;s &lt;em&gt;already in the process&lt;/em&gt; of initializing type A &lt;em&gt;in the same thread&lt;/em&gt;, it continues as if the type were already initialized. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So here&amp;#39;s what you &lt;em&gt;might&lt;/em&gt; expect to happen:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Initialize Test: no further action required &lt;/li&gt;    &lt;li&gt;Start running Main &lt;/li&gt;    &lt;li&gt;Start initializing First (as we need First.Beta) &lt;/li&gt;    &lt;li&gt;Set First.Alpha to 5 &lt;/li&gt;    &lt;li&gt;Start initializing Second (as we need Second.Gamma) &lt;/li&gt;    &lt;li&gt;Set Second.Gamma to First.Alpha (5) &lt;/li&gt;    &lt;li&gt;End initializing Second &lt;/li&gt;    &lt;li&gt;Set First.Beta to Second.Gamma (5) &lt;/li&gt;    &lt;li&gt;End initializing First &lt;/li&gt;    &lt;li&gt;Print 5 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Here&amp;#39;s what &lt;em&gt;actually&lt;/em&gt; happens - on my box, running .NET 4.5 beta. (I know that &lt;a href="https://msmvps.com/blogs/jon_skeet/archive/2010/01/26/type-initialization-changes-in-net-4-0.aspx"&gt;type initialization changed for .NET 4&lt;/a&gt;, for example. I don&amp;#39;t &lt;em&gt;know&lt;/em&gt; of any changes for .NET 4.5, but I&amp;#39;m not going to claim it&amp;#39;s impossible.)&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Initialize Test: no further action required &lt;/li&gt;    &lt;li&gt;Start running Main &lt;/li&gt;    &lt;li&gt;Start initializing First (as we need First.Beta) &lt;/li&gt;    &lt;li&gt;Start initializing Second (we &lt;em&gt;will&lt;/em&gt; need Second.Gamma) &lt;/li&gt;    &lt;li&gt;Set Second.Gamma to First.Alpha (0) &lt;/li&gt;    &lt;li&gt;End initializing Second &lt;/li&gt;    &lt;li&gt;Set First.Alpha to 5 &lt;/li&gt;    &lt;li&gt;Set First.Beta to Second.Gamma (0) &lt;/li&gt;    &lt;li&gt;End initializing First &lt;/li&gt;    &lt;li&gt;Print 0 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Step 5 is the interesting one here. We know that we need First to be initialized, in order to get First.Alpha, but this thread is &lt;em&gt;already&lt;/em&gt; initializing First (we started in step 3) so we just access First.Alpha and hope that it&amp;#39;s got the right value. As it happens, that variable initializer hasn&amp;#39;t been executed yet. Oops.&lt;/p&gt;  &lt;p&gt;(One subtlety here is that I &lt;em&gt;could &lt;/em&gt;have declared all these variables as constants instead using &amp;quot;const&amp;quot; which would have avoided all these problems.)&lt;/p&gt;  &lt;h1&gt;Back in the real world...&lt;/h1&gt;  &lt;p&gt;Hopefully that example makes it clear why circular dependencies in type initializers are nasty. They&amp;#39;re hard to spot, hard to debug, and hard to test. Pretty much your classic &lt;a href="http://en.wikipedia.org/wiki/Heisenbug"&gt;Heisenbug&lt;/a&gt;, really. It&amp;#39;s important to note that if the program above had &lt;em&gt;happened&lt;/em&gt; to initialize Second first (to access a different variable, for example) we could have ended up with a different result. In particular, it&amp;#39;s easy to get into a situation where running &lt;em&gt;all&lt;/em&gt; your unit tests can cause a failure - but if you run &lt;em&gt;just&lt;/em&gt; the failing test, it passes.&lt;/p&gt;  &lt;p&gt;One way of avoiding all of this is never to use any type initializers for anything, of course. In many cases that&amp;#39;s exactly the right solution - but often there &lt;em&gt;are&lt;/em&gt; natural uses, particularly for well-known values such as &lt;a href="http://msdn.microsoft.com/en-us/library/system.text.encoding.utf8.aspx"&gt;Encoding.Utf8&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/system.timezoneinfo.utc.aspx"&gt;TimeZoneInfo.Utc&lt;/a&gt; and the like. Note that in both of those cases they are static &lt;em&gt;properties&lt;/em&gt;, but I would expect them to be backed by static fields. I&amp;#39;m somewhat ambivalent between using public static readonly fields and public static get-only properties - but as we&amp;#39;ll see later, there&amp;#39;s a definite advantage to using properties.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://noda-time.googlecode.com"&gt;Noda Time&lt;/a&gt; has quite a few values like this - partly because so many of its types are immutable. It makes sense to create a single UTC time zone, a single ISO calendar system, a single &amp;quot;pattern&amp;quot; (text formatter/parser) for each of a variety of common cases. In addition to the publicly visible values, there are various static variables used internally, mostly for caching purposes. All of this definitely adds complexity - &lt;em&gt;and&lt;/em&gt; makes it harder to test - but the performance benefits can be significant.&lt;/p&gt;  &lt;p&gt;Unfortunately, a lot of these values end up with fairly natural circular dependencies - as I discovered just recently, where adding a new static field caused all kinds of breakage. I was able to fix the immediate cause, but it left me concerned about the integrity of the code. I&amp;#39;d fixed the one failure I knew about - but what about any others?&lt;/p&gt;  &lt;h1&gt;Testing type initialization&lt;/h1&gt;  &lt;p&gt;One of the biggest issues with type initialization is the order-sensitivity - combined with the way that once a type has been initialized once, that&amp;#39;s it for that AppDomain. As I showed earlier, it&amp;#39;s possible that initializing types in one particular order causes a problem, but a different order won&amp;#39;t.&lt;/p&gt;  &lt;p&gt;I&amp;#39;ve decided that for Noda Time at least, I want to be reasonably sure that type initialization circularity isn&amp;#39;t going to bite me. So I want to validate that no type initializers form cycles, whatever order the types are initialized in. Logically if we can detect a cycle starting with one type, we &lt;em&gt;ought&lt;/em&gt; to be able to detect it starting with any of the other types in that cycle - but I&amp;#39;m sufficiently concerned about weird corner cases that I&amp;#39;d rather just take a brute force approach.&lt;/p&gt;  &lt;p&gt;So, as a rough plan:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Start with an empty set of dependencies &lt;/li&gt;    &lt;li&gt;For each type in the target assembly:      &lt;ul&gt;       &lt;li&gt;Create a new AppDomain &lt;/li&gt;        &lt;li&gt;Load the target assembly into it &lt;/li&gt;        &lt;li&gt;Force the type to be initialized &lt;/li&gt;        &lt;li&gt;Take a stack trace at the start of each type initializer and record any dependencies &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Look for cycles in the complete set of dependencies &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Note that we&amp;#39;ll never spot a cycle within any single AppDomain, due to the way that type initialization works. We have to put together the results for multiple initialization sequences to try to find a cycle.&lt;/p&gt;  &lt;p&gt;A description of the code would probably be harder to follow than the code itself, but the code is relatively long - I&amp;#39;ve included it at the end of this post to avoid intefering with the narrative flow. For more up-to-date versions in the future, look at the &lt;a href="http://code.google.com/p/noda-time/source/browse/"&gt;Noda Time repository&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This &lt;em&gt;isn&amp;#39;t&lt;/em&gt; a terribly nice solution, for various reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Creating a new AppDomain and loading assemblies into it &lt;em&gt;from a unit test runner&lt;/em&gt; isn&amp;#39;t as simple as it might be. My code doesn&amp;#39;t currently work with NCrunch; I don&amp;#39;t know how it finds its assemblies yet. When I&amp;#39;ve fixed that, I&amp;#39;m sure other test runners would still be broken. Likewise I&amp;#39;ve had to explicitly filter types to get TeamCity (the continuous integration system Noda Time uses) to work properly. Currently, you&amp;#39;d need to edit the test code to change the filters. (It&amp;#39;s possible that there are better ways of filtering, of course.) &lt;/li&gt;    &lt;li&gt;It relies on each type within the production code which has an &amp;quot;interesting&amp;quot; type initializer to have a line like this:      &lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; TypeInitializationChecking = NodaTime.Utility.TypeInitializationChecker.RecordInitializationStart(); &lt;/div&gt;   &lt;/li&gt;    &lt;li&gt;Not only does the previous line need to be added to the production code - it clearly gets executed each time, and takes up heap space per type. It&amp;#39;s only 4 bytes for each type involved, and it does no real work when we&amp;#39;re not testing, but it&amp;#39;s a nuisance anyway. I &lt;em&gt;could&lt;/em&gt; use preprocessor directives to remove the code from non-debug or non-test-targeted builds, but that would look even messier. &lt;/li&gt;    &lt;li&gt;It only picks up cycles which occur when running the version of .NET the tests happen to execute on. Given that there are ordering changes for different versions, I wouldn&amp;#39;t like to claim this is 100% bullet-proof. Likewise if there are only cycles when you&amp;#39;re running in some specific cultures (or other environmental features), it won&amp;#39;t necessarily pick those up. &lt;/li&gt;    &lt;li&gt;I&amp;#39;ve deliberately not tried to make the testing code thread-safe. That&amp;#39;s fine in Noda Time - I don&amp;#39;t have any asynchronous operations or new threads in Noda Time at all - but other code may need to make this more robust. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So with all these caveats, is it still worth it? Absolutely: &lt;strong&gt;it&amp;#39;s already found bugs which have now been fixed&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;In fact, the test didn&amp;#39;t get as far as reporting cycles to start with - it turned out that if you initialized one particular type first, the type initializer would fail with a NullReferenceException. Ouch! Once I&amp;#39;d fixed that, there were still quite a few problems to fix. Somewhat coincidentally, fixing them improved the design too - although the user-visible API didn&amp;#39;t change at all.&lt;/p&gt;  &lt;h1&gt;Fixing type initializer cycles&lt;/h1&gt;  &lt;p&gt;In the past, I&amp;#39;ve occasionally &amp;quot;fixed&amp;quot; type initialization ordering problems by simply moving fields around. The cycles still existed, but I figured out how to make them harmless. I can say now that &lt;em&gt;this approach does not scale, and is more effort than it&amp;#39;s worth&lt;/em&gt;. The code ends up being brittle, hard to think about, and once you&amp;#39;ve got more than a couple of types involved it&amp;#39;s really error-prone, at least for my brain. It&amp;#39;s much better to break the cycle completely. To this end, I&amp;#39;ve ended up using a fairly simple technique to defer initialization of static variables. It&amp;#39;s a poor-man&amp;#39;s &lt;a href="http://msdn.microsoft.com/en-us/library/dd642331.aspx"&gt;Lazy&amp;lt;T&amp;gt;&lt;/a&gt;, to some extent - but I&amp;#39;d rather not have to write Lazy&amp;lt;T&amp;gt; myself, and we&amp;#39;re currently targeting .NET 3.5...&lt;/p&gt;  &lt;p&gt;Basically, instead of exposing a public static readonly field which creates the cycle, you expose a public static readonly property - which returns an internal static readonly field &lt;em&gt;in a nested, private static class&lt;/em&gt;. We still get the nice thread-safe once-only initialization of a type initializer, but the nested type won&amp;#39;t be initialized until it needs to be. (In theory it &lt;em&gt;could&lt;/em&gt; be initialized earlier, but a static constructor would ensure it isn&amp;#39;t.) So long as nothing within the &lt;em&gt;rest&lt;/em&gt; of the type initializer for the containing class uses that property, we avoid the cycle.&lt;/p&gt;  &lt;p&gt;So instead of this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Requires Bar to be initialized - if Bar also requires Foo to be&lt;/span&gt;     &lt;br /&gt;&lt;span class="InlineComment"&gt;// initialized, we have a problem...&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Foo SimpleFoo = &lt;span class="Keyword"&gt;new&lt;/span&gt; Foo(Bar.Zero); &lt;/div&gt;  &lt;p&gt;We might have:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Foo SimpleFoo { get { &lt;span class="Statement"&gt;return&lt;/span&gt; Constants.SimpleFoo; } }     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Constants     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; TypeInitializationChecking = NodaTime.Utility.TypeInitializationChecker.RecordInitializationStart();&amp;#160; &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// This requires both Foo and Bar to be initialized, but that&amp;#39;s okay&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// so long as neither of them require Foo.Constants to be initialized.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// (The unit test would spot that.)&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Foo SimpleFoo = &lt;span class="Keyword"&gt;new&lt;/span&gt; Foo(Bar.Zero);     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;I&amp;#39;m currently undecided about whether to include static constructors in these classes to ensure lazy initialization. If the type initializer for Foo triggered the initializer of Foo.Constants, we&amp;#39;d be back to square one... but adding static constructors into each of these nested classes sounds like a bit of a pain. The nested classes should call into the type initialization checking as well, to validate they don&amp;#39;t cause any problems themselves.&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;I have to say, part of me really doesn&amp;#39;t like either the testing code or the workaround. Both smack of being &lt;em&gt;clever&lt;/em&gt;, which is never a good thing. It&amp;#39;s definitely worth considering whether you could actually just get rid of the type initializer (or part of it) entirely, avoiding maintaining so much static state. It would be nice to be able to detect these type initializer cycles without running anything, simply using static analysis - I&amp;#39;m going to see whether NDepend could do that when I get a chance. The workaround doesn&amp;#39;t feel as neat as Lazy&amp;lt;T&amp;gt;, which is &lt;em&gt;really&lt;/em&gt; what&amp;#39;s called for here - but I don&amp;#39;t trust myself to implement it correctly and efficiently myself.&lt;/p&gt;  &lt;p&gt;So while both are somewhat hacky, they&amp;#39;re better than the alternative: buggy code. That&amp;#39;s what I&amp;#39;m ashamed to say I had in Noda Time, and I don&amp;#39;t think I&amp;#39;d &lt;em&gt;ever&lt;/em&gt; have spotted all the cycles by inspection. It&amp;#39;s worth a try on your own code - see whether you&amp;#39;ve got problems lurking...&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Appendix: Testing code&lt;/h1&gt;  &lt;p&gt;As promised earlier, here&amp;#39;s the code for the production and test classes.&lt;/p&gt;  &lt;h2&gt;TypeInitializationChecker&lt;/h2&gt;  &lt;p&gt;This is in NodaTime.dll itself.&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; TypeInitializationChecker : MarshalByRefObject     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; List&amp;lt;Dependency&amp;gt; dependencies = &lt;span class="Keyword"&gt;null&lt;/span&gt;;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; MethodInfo EntryMethod = &lt;span class="Keyword"&gt;typeof&lt;/span&gt;(TypeInitializationChecker).GetMethod(&lt;span class="String"&gt;&amp;quot;FindDependencies&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; RecordInitializationStart()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (dependencies == &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Type previousType = &lt;span class="Keyword"&gt;null&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; frame &lt;span class="Statement"&gt;in&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; StackTrace().GetFrames())     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; method = frame.GetMethod();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (method == EntryMethod)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; declaringType = method.DeclaringType;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (method == declaringType.TypeInitializer)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (previousType != &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dependencies.Add(&lt;span class="Keyword"&gt;new&lt;/span&gt; Dependency(declaringType, previousType));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; previousType = declaringType;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// Invoked from the unit tests, this finds the dependency chain for a single type&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// by invoking its type initializer.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; Dependency[] FindDependencies(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; name)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dependencies = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;Dependency&amp;gt;();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Type type = &lt;span class="Keyword"&gt;typeof&lt;/span&gt;(TypeInitializationChecker).Assembly.GetType(name, &lt;span class="Keyword"&gt;true&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RuntimeHelpers.RunClassConstructor(type.TypeHandle);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; dependencies.ToArray();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// A simple from/to tuple, which can be marshaled across AppDomains.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Dependency : MarshalByRefObject     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; From { get; &lt;span class="Modifier"&gt;private&lt;/span&gt; set; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; To { get; &lt;span class="Modifier"&gt;private&lt;/span&gt; set; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt; Dependency(Type &lt;span class="Linq"&gt;from&lt;/span&gt;, Type to)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; From = &lt;span class="Linq"&gt;from&lt;/span&gt;.FullName;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; To = to.FullName;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;h2&gt;TypeInitializationTest&lt;/h2&gt;  &lt;p&gt;This is within NodaTime.Test:&lt;/p&gt;  &lt;div class="code"&gt;[TestFixture]    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; TypeInitializationTest     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [Test]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; BuildInitializerLoops()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Assembly assembly = &lt;span class="Keyword"&gt;typeof&lt;/span&gt;(TypeInitializationChecker).Assembly;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; dependencies = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;TypeInitializationChecker.Dependency&amp;gt;();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Test each type in a new AppDomain - we want to see what happens where each type is initialized first.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Note: Namespace prefix check is present to get this to survive in test runners which&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// inject extra types. (Seen with JetBrains.Profiler.Core.Instrumentation.DataOnStack.)&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; type &lt;span class="Statement"&gt;in&lt;/span&gt; assembly.GetTypes().Where(t =&amp;gt; t.FullName.StartsWith(&lt;span class="String"&gt;&amp;quot;NodaTime&amp;quot;&lt;/span&gt;)))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Note: this won&amp;#39;t be enough to load the assembly in all test runners. In particular, it fails in&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// NCrunch at the moment.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AppDomainSetup setup = &lt;span class="Keyword"&gt;new&lt;/span&gt; AppDomainSetup { ApplicationBase = AppDomain.CurrentDomain.BaseDirectory };     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AppDomain domain = AppDomain.CreateDomain(&lt;span class="String"&gt;&amp;quot;InitializationTest&amp;quot;&lt;/span&gt; + type.Name, AppDomain.CurrentDomain.Evidence, setup);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; helper = (TypeInitializationChecker)domain.CreateInstanceAndUnwrap(assembly.FullName,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;typeof&lt;/span&gt;(TypeInitializationChecker).FullName);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; dependencies.AddRange(helper.FindDependencies(type.FullName));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; lookup = dependencies.ToLookup(d =&amp;gt; d.From, d =&amp;gt; d.To);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// This is less efficient than it might be, but I&amp;#39;m aiming for simplicity: starting at each type&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// which has a dependency, can we make a cycle?&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// See Tarjan&amp;#39;s Algorithm in Wikipedia for ways this could be made more efficient.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// http://en.wikipedia.org/wiki/Tarjan&amp;#39;s_strongly_connected_components_algorithm&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt;&amp;#160;&lt;span class="Linq"&gt;group&lt;/span&gt;&amp;#160;&lt;span class="Statement"&gt;in&lt;/span&gt; lookup)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Stack&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; path = &lt;span class="Keyword"&gt;new&lt;/span&gt; Stack&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CheckForCycles(&lt;span class="Linq"&gt;group&lt;/span&gt;.Key, path, lookup);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; CheckForCycles(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; next, Stack&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; path, ILookup&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; dependencyLookup)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (path.Contains(next))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Assert.Fail(&lt;span class="String"&gt;&amp;quot;Type initializer cycle: {0}-{1}&amp;quot;&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;.Join(&lt;span class="String"&gt;&amp;quot;-&amp;quot;&lt;/span&gt;, path.Reverse().ToArray()), next);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; path.Push(next);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; candidate &lt;span class="Statement"&gt;in&lt;/span&gt; dependencyLookup[next].Distinct())     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CheckForCycles(candidate, path, dependencyLookup);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; path.Pop();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1808561" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/aF_dVyhKyCg" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/04/07/type-initializer-circular-dependencies.aspx</feedburner:origLink></item><item><title>Diagnosing weird problems - a Stack Overflow case study</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/CIaupaq9SkE/diagnosing-weird-problems-a-stack-overflow-case-study.aspx</link><pubDate>Fri, 16 Mar 2012 06:31:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1807429</guid><dc:creator>skeet</dc:creator><slash:comments>14</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1807429</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1807429</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/03/16/diagnosing-weird-problems-a-stack-overflow-case-study.aspx#comments</comments><description>&lt;p&gt;Earlier, I came across &lt;a href="http://stackoverflow.com/questions/9728056"&gt;this Stack Overflow question&lt;/a&gt;. I solved it, tweeted it, but then thought it would serve as a useful case study into the mental processes I go through when trying to solve a problem - whether that&amp;#39;s on Stack Overflow, at work, or at home.&lt;/p&gt;  &lt;p&gt;It&amp;#39;s definitely worth reading the original question, but the executive summary is:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;When I compute the checksum/hash of c:\Windows\System32\Calc.exe using various tools and algorithms, those tools all give the same answer for each algorithm. When I try doing the same thing in Java, I get different results. What&amp;#39;s going on?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now to start with, I&amp;#39;d like to shower a bit of praise on the author:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The post came with a short but utterly complete program to demonstrate the problem &lt;/li&gt;    &lt;li&gt;The comments in the program showed the expected values and the actual values &lt;/li&gt;    &lt;li&gt;The code was mostly pretty clean (clean enough for an SO post anyway) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In short, it had pretty much &lt;a href="http://tinyurl.com/so-hints"&gt;everything I ask for in a question&lt;/a&gt;. Yay! Additionally, the result seemed to be strange. The chances of any one of Java&amp;#39;s hashing algorithms being broken seem pretty slim, but &lt;em&gt;four&lt;/em&gt; of them? Okay, now you&amp;#39;ve got me interested. &lt;/p&gt;  &lt;h3&gt;Reproducing the problem&lt;/h3&gt;  &lt;p&gt;Unless I can spot the error immediately, I usually try to reproduce the problem in a Stack Overflow post with a short but complete program. In this case, the program was already provided, so it was just a matter of copy/paste/compile/run. This one had the additional tweak that it was comparing the results of Java with the results of other tools, so I had to get hold of an MD5 sum tool first. (I chose to start with MD5 for no particular reason.) I happened to pick &lt;a href="http://www.pc-tools.net/win32/md5sums/"&gt;this one&lt;/a&gt;, but it didn&amp;#39;t really seem it would make much difference. (As it happens, that was an incorrect assumption, but hey...)&lt;/p&gt;  &lt;p&gt;I ran md5sums on c:\Windows\System32\calc.exe, and got the same result as the poster. Handy.&lt;/p&gt;  &lt;p&gt;I then ran the Java code, and again got the same result as the poster: step complete, we have a discrepancy between at least one tool (and MD5 isn&amp;#39;t that hard to get right) and Java.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Looking for obvious problems&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The code has four main areas:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Reading a file &lt;/li&gt;    &lt;li&gt;Updating digests &lt;/li&gt;    &lt;li&gt;Converting bytes to hex &lt;/li&gt;    &lt;li&gt;Storing and displaying results &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Of these, all of the first three have common and fairly simple error modes. For example:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Failure to use the return value from InputStream.read() &lt;/li&gt;    &lt;li&gt;Failure to update the digests using only the relevant portion of the data buffer &lt;/li&gt;    &lt;li&gt;Failure to cope with Java&amp;#39;s signed bytes &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The code for storing and displaying results seemed solid enough to ignore to start with, and brief inspection suggested that the first two failure modes had been avoided. While the hex code didn&amp;#39;t have any &lt;em&gt;obvious&lt;/em&gt; problems either, it made sense to check it. I simply printed the result of hard-coding the &amp;quot;known good&amp;quot; CRC-32 value:&lt;/p&gt;  &lt;div class="code"&gt;System.out.println(toHex(&lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;#160;&lt;span class="Type"&gt;byte&lt;/span&gt;[] {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (&lt;span class="Type"&gt;byte&lt;/span&gt;) 0x8D, (&lt;span class="Type"&gt;byte&lt;/span&gt;) 0x8F, (&lt;span class="Type"&gt;byte&lt;/span&gt;) 0x5F, (&lt;span class="Type"&gt;byte&lt;/span&gt;) 0x8E     &lt;br /&gt;&amp;#160; })); &lt;/div&gt;  &lt;p&gt;That produced the right result, so I ruled out that part of the code too. Even if it had errors in some cases, we know it&amp;#39;s capable of producing the right string for one of the values we know we &lt;em&gt;should&lt;/em&gt; be returning, so it can&amp;#39;t be getting that value.&lt;/p&gt;  &lt;h3&gt;Initial checks around the file&lt;/h3&gt;  &lt;p&gt;I&amp;#39;m always suspicious of stream-handling code - or rather, I know how easily it can hide subtle bugs. Even though it &lt;em&gt;looked&lt;/em&gt; okay, I thought I&amp;#39;d check - so I added a simple total to the code so I could see how many bytes had been hashed. I also removed all the hash algorithms other than MD5, just for simplicity:&lt;/p&gt;  &lt;div class="code"&gt;MessageDigest md5 = MessageDigest.getInstance(&lt;span class="String"&gt;&amp;quot;MD5&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;FileInputStream fis = &lt;span class="Keyword"&gt;new&lt;/span&gt; FileInputStream(file);     &lt;br /&gt;&lt;span class="Type"&gt;byte&lt;/span&gt; data[] = &lt;span class="Keyword"&gt;new&lt;/span&gt;&amp;#160;&lt;span class="Type"&gt;byte&lt;/span&gt;[size];     &lt;br /&gt;&lt;span class="Type"&gt;int&lt;/span&gt; len = 0;     &lt;br /&gt;&lt;span class="Type"&gt;int&lt;/span&gt; total = 0;     &lt;br /&gt;&lt;span class="Statement"&gt;while&lt;/span&gt; ((len = fis.read(data)) != -1) {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; md5.update(data, 0, len);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; total += len;     &lt;br /&gt;}     &lt;br /&gt;fis.close();     &lt;br /&gt;System.out.println(&lt;span class="String"&gt;&amp;quot;Total bytes read: &amp;quot;&lt;/span&gt; + total);     &lt;br /&gt;    &lt;br /&gt;results.put(md5.getAlgorithm(), toHex(md5.digest())); &lt;/div&gt;  &lt;p&gt;It&amp;#39;s worth noting that I &lt;em&gt;haven&amp;#39;t&lt;/em&gt; tried to fix up bits of the code which I know I would change if I were actually doing a code review:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The stream isn&amp;#39;t being closed in a finally block, so we&amp;#39;ll have a dangling resource (until GC) if an IOException is thrown &lt;/li&gt;    &lt;li&gt;The initial value of len is never read, and can be removed &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Neither of these matters in terms of the problem at hand, and closing the file &amp;quot;properly&amp;quot; would make the sample code more complicated. (For the sake of just a short sample program, I&amp;#39;d be tempted to remove it entirely.)&lt;/p&gt;  &lt;p&gt;The result showed the number of bytes being read as the command prompt did when I ran &amp;quot;dir c:\Windows\System32\Calc.exe&amp;quot; - so again, everything looks like it&amp;#39;s okay.&lt;/p&gt;  &lt;h3&gt;Desperate times call for stupid measures&lt;/h3&gt;  &lt;p&gt;Just on a whim, I decided to copy Calc.exe to a local folder (the current directory) and retry. After all, accessing a file in a system folder &lt;em&gt;might&lt;/em&gt; have some odd notions applied to it. It&amp;#39;s hard to work out what, but... there&amp;#39;s nothing to lose just by trying a simple test. If it can rule &lt;em&gt;anything&lt;/em&gt; out, and you&amp;#39;ve got no better ideas, you might as well try even the daftest idea.&lt;/p&gt;  &lt;p&gt;I modified the source code to use the freshly-copied file, and it gave the same result. Hmm.&lt;/p&gt;  &lt;p&gt;I then reran md5sums on the copied file... and it gave &lt;em&gt;the same result as Java&lt;/em&gt;. In other words, running &amp;quot;md5sums c:\Windows\System32\Calc.exe&amp;quot; gave one result, but &amp;quot;md5sums CopyOfCalc.exe&amp;quot; gave a different result. At this point we&amp;#39;ve moved from &lt;em&gt;Java&lt;/em&gt; looking like it&amp;#39;s behaving weirdly to &lt;em&gt;md5sums&lt;/em&gt; looking suspicious.&lt;/p&gt;  &lt;h3&gt;Proving the root cause&lt;/h3&gt;  &lt;p&gt;At this point we&amp;#39;re &lt;em&gt;sort of&lt;/em&gt; done - we&amp;#39;ve basically proved that the Java code produces the right hash for whatever data it&amp;#39;s given, but we&amp;#39;re left with the question of what&amp;#39;s happening on the file system. I had a hunch that it might be something to do with x86 vs x64 code (all of this was running on a 64-bit version of Windows 7) - so how do we test that assumption?&lt;/p&gt;  &lt;p&gt;I don&amp;#39;t know if there&amp;#39;s a simple way of running an x86 version of the JVM, but I &lt;em&gt;do&lt;/em&gt; know how to switch .NET code between x86 and x64 - you can do that for an assembly at build time. C# also makes the hashing and hex conversion simple, so I was able to knock up a very small app to show the problem:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;     &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.IO;     &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Security.Cryptography;     &lt;br /&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Namespace"&gt;using&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; md5 = MD5.Create())     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ReferenceType"&gt;string&lt;/span&gt; path = &lt;span class="String"&gt;&amp;quot;c:/Windows/System32/Calc.exe&amp;quot;&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; bytes = md5.ComputeHash(File.ReadAllBytes(path));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(BitConverter.ToString(bytes));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;(For a larger file I&amp;#39;d have used File.OpenRead instead, but then I&amp;#39;d have wanted to close the stream afterwards. Somehow it wasn&amp;#39;t worth correcting the &lt;em&gt;existing&lt;/em&gt; possible handle leak in the Java code, but I didn&amp;#39;t want to write leaky code myself. So instead I&amp;#39;ve got code which reads the whole file into memory unnecessarily... &amp;lt;sigh&amp;gt;)&lt;/p&gt;  &lt;p&gt;You can choose the architecture to build against (usually AnyCPU, x86 or x64 - though it&amp;#39;s interesting to see that &amp;quot;arm&amp;quot; is also an option under .NET 4.5, for obvious reasons) either from Visual Studio or using the &amp;quot;/platform&amp;quot; command line option. This doesn&amp;#39;t change the IL emitted (as far as I&amp;#39;m aware) but it&amp;#39;s used for interop with native code - and in the case of executables, it also determines the version of the CLR which is used.&lt;/p&gt;  &lt;p&gt;Building and running in x86 mode gave the same answer as the original &amp;quot;assumed to be good&amp;quot; tools; building and running in x64 mode gave the same answer as Java.&lt;/p&gt;  &lt;h3&gt;Explaining the root cause&lt;/h3&gt;  &lt;p&gt;At this point we&amp;#39;ve proved that the file system gives different results depending on whether you access it from a 64-bit process or a 32-bit process. The &lt;em&gt;final&lt;/em&gt; piece of the puzzle was to find some something to explain why that happens. With all the evidence about what&amp;#39;s happening, it was now easy to search for more information, and I found &lt;a href="http://www.samlogic.net/articles/32-64-bit-windows-folder-x86-syswow64.htm"&gt;this article&lt;/a&gt; giving satisfactory details. Basically, there are two different copies of the system executables on a 64 bit system: x86 ones which run under the 32-bit emulator, and x64 ones. They&amp;#39;re actually in different directories, but when a process opens a file in \Windows\System32, the copy which matches the architecture of the process is used. It&amp;#39;s almost as if the \Windows\System32 directory is a symlink which changes target depending on the current process.&lt;/p&gt;  &lt;p&gt;A Stack Overflow comment on my answer gave a final nugget that this is called the &amp;quot;File System Redirector&amp;quot;.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;Debugging sessions often feel a bit like this - particularly if you&amp;#39;re like me, and only resort to &lt;em&gt;real&lt;/em&gt; debugging after unit testing has failed. It&amp;#39;s a matter of looking under all kinds of rocks, trying anything and everything, but keeping track of everything you try. At the end of process you should be able to explain &lt;em&gt;every&lt;/em&gt; result you&amp;#39;ve seen, in an ideal world. (You may not be able to give evidence of the actual chain of events, but you should be able to construct a plausible chain of events which concurs with your theory.)&lt;/p&gt;  &lt;p&gt;Be aware of areas which can &lt;em&gt;often&lt;/em&gt; lead to problems, and check those first, gradually reducing the scope of &amp;quot;stuff you don&amp;#39;t understand&amp;quot; to a manageable level, until it disappears completely.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1807429" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/CIaupaq9SkE" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/03/16/diagnosing-weird-problems-a-stack-overflow-case-study.aspx</feedburner:origLink></item><item><title>Eduasync 20: Changes between the VS11 Preview and the Visual Studio 11 Beta</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/RJXvEh-Qhn4/eduasync-20-changes-between-the-vs11-preview-and-the-visual-studio-11-beta.aspx</link><pubDate>Tue, 06 Mar 2012 19:54:54 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1807031</guid><dc:creator>skeet</dc:creator><slash:comments>8</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1807031</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1807031</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/03/06/eduasync-20-changes-between-the-vs11-preview-and-the-visual-studio-11-beta.aspx#comments</comments><description>&lt;p&gt;A while I ago I &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2012/01/12/eduasync-part-18-changes-between-the-async-ctp-and-the-visual-studio-11-preview.aspx"&gt;blogged about&lt;/a&gt; what had changed under the hood of async between the CTP and the VS11 Preview. Well, now that the VS11 Beta is out, it&amp;#39;s time to do it all again...&lt;/p&gt;  &lt;p&gt;Note that the code in this post &lt;em&gt;is &lt;/em&gt;in the &lt;a href="http://eduasync.googlecode.com"&gt;Eduasync codebase&lt;/a&gt;, under a different solution (Eduasync VS11.sln). Many of the old existing projects won&amp;#39;t compile with VS11 beta, but I&amp;#39;d rather leave them as they are for posterity, showing the evolution of the feature.&lt;/p&gt;  &lt;p&gt;Stephen Toub has an &lt;a href="http://blogs.msdn.com/b/pfxteam/archive/2012/02/29/10274035.aspx"&gt;excellent blog post&lt;/a&gt; covering some of this, so while I&amp;#39;ll &lt;em&gt;mention&lt;/em&gt; things he&amp;#39;s covered, I won&amp;#39;t go into much detail about them. Let&amp;#39;s start off there though...&lt;/p&gt;  &lt;p&gt;(EDIT: Stephen has also mailed me with some corrections, which I&amp;#39;ve edited in - mostly without indication, as the post has been up for less than seven hours, and it&amp;#39;ll make for a better reading experience.)&lt;/p&gt;  &lt;h2&gt;Awaiter pattern changes&lt;/h2&gt;  &lt;p&gt;The awaiter pattern is now not &lt;em&gt;just&lt;/em&gt; a pattern. The IsCompleted property and GetResult method are still &amp;quot;loose&amp;quot; but &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.inotifycompletion.oncompleted(v=vs.110).aspx"&gt;OnCompleted&lt;/a&gt; is now part of an interface: &lt;a href="http://msdn.microsoft.com/en-us/library/hh472348(v=vs.110).aspx"&gt;INotifyCompletion&lt;/a&gt;. Awaiters &lt;em&gt;have&lt;/em&gt; to implement INotifyCompleted, but may &lt;em&gt;also&lt;/em&gt; implement &lt;a href="http://msdn.microsoft.com/en-us/library/hh472362(v=vs.110).aspx"&gt;ICriticalNotifyCompletion&lt;/a&gt; and its &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.icriticalnotifycompletion.unsafeoncompleted(v=vs.110).aspx"&gt;UnsafeOnCompleted&lt;/a&gt; method.&lt;/p&gt;  &lt;p&gt;The OnCompleted method is just as it was before, and needs to flow the execuction context; the UnsafeOnCompleted method is simpler, as it &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; need to flow the execution context. All of this only matters if you&amp;#39;re implementing your own awaiters, of course. (More details in Stephen&amp;#39;s blog post. I&amp;#39;ve found this area somewhat confusing, so please do read his post carefully!)&lt;/p&gt;  &lt;h2&gt;Skeleton method changes&lt;/h2&gt;  &lt;p&gt;Just as I have previously, I&amp;#39;m using the (entirely unofficial) term &amp;quot;skeleton method&amp;quot; to mean the very short method created by the compiler with the same signature as an async method: this is the entry point to the async method, effectively, which creates and starts the state machine containing all the &lt;em&gt;real&lt;/em&gt; logic.&lt;/p&gt;  &lt;p&gt;There are two changes I&amp;#39;ve noticed in the skeleton method. Firstly, for some reason the state machine state numbers have changed. Whereas previously a state number of 0 meant &amp;quot;initial or running&amp;quot;, positive values meant &amp;quot;between calls, or navigating back to the await expression&amp;quot; and -1 meant &amp;quot;finished&amp;quot;, now -1 means &amp;quot;initial or running&amp;quot;, non-negative means &amp;quot;between calls, or navigating back to await expression&amp;quot; and -2 means &amp;quot;finished&amp;quot;. It&amp;#39;s not clear why this change has been made, given that it requires an extra assignment at the start of every skeleton method (to set the state to -1).&lt;/p&gt;  &lt;p&gt;More importantly, the skeleton method no longer calls MoveNext directly on the state machine that it&amp;#39;s built. Instead, it calls &lt;a href="http://msdn.microsoft.com/en-us/library/hh472313(v=vs.110).aspx"&gt;Start&amp;lt;TStateMachine&amp;gt;&lt;/a&gt; on the &lt;a href="http://msdn.microsoft.com/en-us/library/hh138506(v=vs.110).aspx"&gt;AsyncTaskMethodBuilder&amp;lt;T&amp;gt;&lt;/a&gt; (or whichever method builder it&amp;#39;s using). It passes the state machine by reference (presumably for efficiency), and TStateMachine is constrained to implement the now-public-and-in-mscorlib &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.iasyncstatemachine(v=vs.110).aspx"&gt;IAsyncStateMachine&lt;/a&gt; interface. I&amp;#39;ll come back to the relationship between the state machine and the builder later on.&lt;/p&gt;  &lt;h2&gt;Task caching&lt;/h2&gt;  &lt;p&gt;(Code is in project 30: &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FTaskCaching"&gt;TaskCaching&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;It&amp;#39;s possible for an async method to complete entirely synchronously. In this situation, the result is known before the method returns, and the task returned by the method is already in the RanToCompletionState. If two tasks have already run to completion with the same value, they can be (apparently) regarded as equivalent... so the beta now caches a task in this situation, for some types and values. (Apparently the preview cached too, but I hadn&amp;#39;t noticed, and the beta caches more.) According to my experiments and some comments:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;For int, tasks with values -1 to 8 inclusive are cached &lt;/li&gt;    &lt;li&gt;For bool, both values (true and false)&lt;/li&gt;    &lt;li&gt;For char, byte, sbyte, short, ushort, uint, long, ulong, IntPtr and UIntPtr tasks with value 0 (or &amp;#39;\0&amp;#39;) are cached &lt;/li&gt;    &lt;li&gt;For reference types, null is cached&lt;/li&gt;    &lt;li&gt;For other types, no tasks are cached&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;EDIT: After they&amp;#39;ve completed, tasks are normally immutable &lt;em&gt;except for disposal&lt;/em&gt; - the cached tasks are tweaked slightly to make disposal a no-op. &lt;/p&gt;  &lt;h2&gt;State machine interface changes&lt;/h2&gt;  &lt;p&gt;In the VS11 preview release, each state machine implemented an interface, but that interface was internal to the generated assembly, and contained a single method (SetMoveNextDelegate). It&amp;#39;s now a public interface with two methods:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.iasyncstatemachine.movenext(v=vs.110).aspx"&gt;MoveNext&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.iasyncstatemachine.setstatemachine(v=vs.110).aspx"&gt;SetStateMachine&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Personally I&amp;#39;m not keen on the naming of &amp;quot;MoveNext&amp;quot; - I can&amp;#39;t help but feel that if we didn&amp;#39;t have the &amp;quot;naming baggage&amp;quot; of IEnumerator and the fact that at least early on, the code generator was very similar to that used for iterator blocks, we&amp;#39;d have something different. (It &lt;em&gt;is&lt;/em&gt; moving to the next state of the state machine, but it still doesn&amp;#39;t quite feel right.) I&amp;#39;d favour something like &amp;quot;ContinueExecution&amp;quot;. However, it doesn&amp;#39;t matter - it obviously does what you&amp;#39;d expect, and you&amp;#39;re not going to be calling this yourself.&lt;/p&gt;  &lt;p&gt;SetStateMachine is a stranger beast. The documentation states:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Configures the state machine with a heap-allocated replica.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;... which says almost nothing, really. The implementation is always simple, just like SetMoveNextDelegate was, although this time it delegates to the builder for the real work (a common theme, as we&amp;#39;ll see):&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="ValueType"&gt;void&lt;/span&gt; IAsyncStateMachine.SetStateMachine(IAsyncStateMachine param0)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;t__builder.SetStateMachine(param0);     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Now &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.asynctaskmethodbuilder.setstatemachine(v=vs.110).aspx"&gt;AsyncTaskMethodBuilder.SetStateMachine&lt;/a&gt; is also documented pretty sparsely:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Associates the builder with the specified state machine.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Again, no real help. However, we&amp;#39;ll see that it&amp;#39;s the &lt;em&gt;builder&lt;/em&gt; which is responsible for calling OnContinue now, and as it can call MoveNext on an IStateMachine, it makes sense to tell it which state machine it&amp;#39;s associated with... but can&amp;#39;t it do that directly?&lt;/p&gt;  &lt;p&gt;Well, not quite. The problem (as I understand it) is around when boxing occurs. We initially create the state machine on the stack, and it contains the builder. (Both are structs.) That&amp;#39;s fine until we need a continuation, but then we&amp;#39;ve got to be able to get back to the current state later, after the current stack frame has been blown away. So we need to box the state machine. That will create a &lt;em&gt;copy&lt;/em&gt; of the current builder (within the box). We need the builder within the boxed state machine to contain a reference to the same box. So the order has to be:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Box the state machine &lt;/li&gt;    &lt;li&gt;Tell the state machine about the boxed reference &lt;/li&gt;    &lt;li&gt;The state machine tells its nested builder about the boxed reference &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Back when the state machine was in charge of the boxing, this went via the delegate: the act of creating the box was implicit when creating the delegate, and then casting the delegate target to the interface type allowed a reference to the newly-created delegate to be set within the copy. This is similar, but using the builder instead. It&amp;#39;s hard to follow, but of course it&amp;#39;s not going to matter.&lt;/p&gt;  &lt;h2&gt;State machine field changes&lt;/h2&gt;  &lt;p&gt;There are various kinds of fields in the state machine:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Those corresponding with local variables and parameters in the async method &lt;/li&gt;    &lt;li&gt;The state &lt;/li&gt;    &lt;li&gt;The field(s) associated with awaiters &lt;/li&gt;    &lt;li&gt;(In the preview/beta) The field associated with the &amp;quot;current execution stack&amp;quot; at the point of an await expression &lt;/li&gt;    &lt;li&gt;(In the CTP) An unused &amp;quot;disposing&amp;quot; field &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Of these, I believe only the awaiters have actually changed, but before we talk about that, let&amp;#39;s revisit local variables.&lt;/p&gt;  &lt;h3&gt;Local variable hoisting&lt;/h3&gt;  &lt;p&gt;I&amp;#39;ve just noticed that the local variables are only hoisted to fields when its scope contains an await expressions, but in that case &lt;em&gt;all&lt;/em&gt; local variables of that scope are hoisted, whether or not they&amp;#39;re used &amp;quot;across&amp;quot; awaits. It would be possible to hoist only those which need to be maintained between executions, but then you wouldn&amp;#39;t be able to see the others when debugging, which would be somewhat confusing. Likewise local variables of the same type which are never propagated across the same await &lt;em&gt;could&lt;/em&gt; be aliased. For example, consider this async method:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt; Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; M(Random rng)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; x = rng.Next(1000);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; y = x + rng.Next(1000);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; Task.Yield();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; z = y + rng.Next(1000);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; Task.Yield();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; z;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;If the compiler could be confident you didn&amp;#39;t need to debug through this code, it &lt;em&gt;could&lt;/em&gt; make do with one field of type &amp;quot;Random&amp;quot; and one field of type &amp;quot;int&amp;quot; - x can be a completely local variable in MoveNext (it&amp;#39;s not used between two awaits) and y and z can be aliased (we never need the value of y after we&amp;#39;ve first written to z).&lt;/p&gt;  &lt;p&gt;Local variable aliasing probably isn&amp;#39;t particularly useful for &amp;quot;normal&amp;quot; methods as the JIT may be able to do it (so long as you don&amp;#39;t have a debugger attached, potentially) but in this case we expect the state machine to be boxed at some point, so potentially &lt;em&gt;does&lt;/em&gt; make a difference (while the stack is typically reasonably small, you could have a &lt;em&gt;lot&lt;/em&gt; of outstanding async methods in some scenarios). Maybe in a future release, the C# compiler could have an aggressive optimization mode around this, to be turned on explicitly. (I don&amp;#39;t think it should be&amp;#160; a particularly high priority, mind you.)&lt;/p&gt;  &lt;h3&gt;Awaiter fields&lt;/h3&gt;  &lt;p&gt;(Code is in project 31, &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FAwaiterFields"&gt;AwaiterFields&lt;/a&gt;.)&lt;/p&gt;  &lt;p&gt;Awaiter fields have changed a bit over the course of async&amp;#39;s history.&lt;/p&gt;  &lt;p&gt;In the CTPs (all of them, I believe) each await expression had its own awaiter field in the state machine, with a type corresponding to the declared awaiter type from the awaitable. (Remember that the awaitable is the thing you await, such as a task, and the awaiter is what you get back from calling GetAwaiter on the awaitable).&lt;/p&gt;  &lt;p&gt;In the VS11 Preview, there was always a single awaiter field of type object. From what I saw, it was usually populated with a single-element array containing an awaiter. For value type awaiters (i.e. where the awaiter is a struct) this is somewhat similar to boxing, but maintaining strong typing, so calls to IsCompleted etc can still be made. It&amp;#39;s possible that reference type awaiters were stored without the array creation, as it would serve no purpose. (I don&amp;#39;t have any machines with just the preview installed to verify this.)&lt;/p&gt;  &lt;p&gt;In the Beta, we have a mixture. If there are any reference type awaiters, they all end up being stored in a single field of type object, which is then cast back to the actual type when required. (Don&amp;#39;t forget that only one awaiter can be &amp;quot;active&amp;quot; at a time, which makes this possible.) This includes awaiters of an interface type - it&amp;#39;s only the &lt;em&gt;compile-time&lt;/em&gt; type declared as the return type of the GetAwaiter method of the awaitable which is important.&lt;/p&gt;  &lt;p&gt;If any of the awaiter types are value types, each of these types gets its own field. So there might be a TaskAwaiter&amp;lt;int&amp;gt; field and a TaskAwaiter&amp;lt;string&amp;gt; field, for example. However, there can still be &amp;quot;sharing&amp;quot; going on: if there are multiple await expressions all of the same value type awaiter, they will all share a single field. (This all feels a &lt;em&gt;little&lt;/em&gt; like the JITting of generics, but it&amp;#39;s somewhat coincidental.)&lt;/p&gt;  &lt;h2&gt;MoveNext method changes&lt;/h2&gt;  &lt;p&gt;(Code is in project 32, BetaStateMachine)&lt;/p&gt;  &lt;p&gt;As I&amp;#39;ve mentioned earlier, the builder is now responsible for a lot more of the work than it was in earlier versions. The majority of the code remains the same as far as I can tell, in terms of handling branching, evaluating expressions with multiple await expressions and so on.&amp;#160; The code in the source repository shows what the complete state machine looks like, but for the sake of clarity, I&amp;#39;ll just focus on a single snippet. If we have an await expression like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;await&lt;/span&gt; x; &lt;/div&gt;  &lt;p&gt;then the state machine code in the VS11 Preview would look something like this:&lt;/p&gt;  &lt;div class="code"&gt;localTaskAwaiter = x.GetAwaiter();    &lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt; (localTaskAwaiter.IsCompleted)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;goto&lt;/span&gt; AwaitCompleted;     &lt;br /&gt;}     &lt;br /&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;.state = 1;     &lt;br /&gt;TaskAwaiter[] awaiterArray = { localTaskAwaiter };     &lt;br /&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;.awaiter = awaiterArray;     &lt;br /&gt;Action continuation = &lt;span class="Keyword"&gt;this&lt;/span&gt;.MoveNextDelegate;     &lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt; (continuation == &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; task = &lt;span class="Keyword"&gt;this&lt;/span&gt;.builder.Task;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; continuation = MoveNext;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ((IStateMachine) continuation.Target).SetMoveNextDelegate(continuation);     &lt;br /&gt;}     &lt;br /&gt;awaiterArray[0].OnCompleted(continuation);     &lt;br /&gt;...     &lt;br /&gt;&lt;span class="Statement"&gt;return&lt;/span&gt;; &lt;/div&gt;  &lt;p&gt;(That&amp;#39;s just setting up the await, of course - there&amp;#39;s then the bit where the result is fetched, but that&amp;#39;s less interesting. There&amp;#39;s also the matter of doFinallyBodies.)&lt;/p&gt;  &lt;p&gt;In the VS11 Beta, it&amp;#39;s something this instead (for an awaiter type &amp;quot;AwaiterType&amp;quot; which implements ICriticalNotifyCompletion, in a state machine of type ThisStateMachine).&lt;/p&gt;  &lt;div class="code"&gt;localAwaiter = x.GetAwaiter();    &lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt; (!localAwaiter.IsCompleted)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; state = 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; awaiterField = localAwaiter;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; builder.AwaitUnsafeOnCompleted&amp;lt;AwaiterType, ThisStateMachine&amp;gt;(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; localAwaiter, &lt;span class="MethodParameter"&gt;ref&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;this&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; doFinallyBodies = &lt;span class="Keyword"&gt;false&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;If the awaiter type only implements INotifyCompletion, it calls &lt;a href="http://msdn.microsoft.com/en-us/library/hh472321(v=vs.110).aspx"&gt;AwaitOnCompleted&lt;/a&gt; instead. Note how the calls are generic (but both type variables are constrained to implement appropriate interfaces) which avoids boxing.&lt;/p&gt;  &lt;p&gt;The call to the builder will call &lt;em&gt;back&lt;/em&gt; to the state machine&amp;#39;s SetStateMachine method if this is the first awaiter that hasn&amp;#39;t already completed within this execution of the async method. So that handles the section which checked for the continuation being null in the first block of code. Most of the rest of the change is explained by the difference in awaiter types, and obviously AwaitOnCompleted/AwaitUnsafeOnCompleted &lt;em&gt;also&lt;/em&gt; ends up calling into OnCompleted on the awaiter itself.&lt;/p&gt;  &lt;h2&gt;Mutable value type awaiters&lt;/h2&gt;  &lt;p&gt;(Code is in project 32, &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FMutableAwaiters"&gt;MutableAwaiters&lt;/a&gt;)&lt;/p&gt;  &lt;p&gt;One subtle difference which &lt;em&gt;really&lt;/em&gt; shouldn&amp;#39;t hurt people but is fun to explore is what happens if you have an awaiter which is a mutable value type. Due to the way awaiters were carefully handled pre-beta, mutations which were conducted as part of OnCompleted would still be visible in GetResult. That&amp;#39;s &lt;em&gt;not&lt;/em&gt; the case in the beta (as Stephen mentions in his blog post). Mind you, it doesn&amp;#39;t mean that &lt;em&gt;all&lt;/em&gt; mutations will be ignored... just ones in OnCompleted. A mutation from IsCompleted is still visible, as shown here:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;struct&lt;/span&gt; MutableAwaiter : INotifyCompletion     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; message;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; MutableAwaiter(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; message)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.message = message;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;bool&lt;/span&gt; IsCompleted     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; message = &lt;span class="String"&gt;&amp;quot;Set in IsCompleted&amp;quot;&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;false&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; OnCompleted(Action action)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; message = &lt;span class="String"&gt;&amp;quot;Set in OnCompleted&amp;quot;&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Ick! Completes inline. Never mind, it&amp;#39;s only a demo...&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; action();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; GetResult()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; message;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;What would you expect to be returned from this awaiter? You can verify that all three members are called... but &amp;quot;Set in IsCompleted&amp;quot; is returned. That&amp;#39;s because IsCompleted is called &lt;em&gt;before&lt;/em&gt; the awaiter value is copied into a field within the state machine. Even though the state machine passes the awaiter by reference, it&amp;#39;s passing the &lt;em&gt;local&lt;/em&gt; variable, which is of course a separate variable from the field.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m &lt;em&gt;absolutely not&lt;/em&gt; suggesting that you should rely on any of this behaviour. If you really need to be able to mutate your awaiter, make it a reference type.&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;The main changes in the Beta are around the interactions between the AsyncTaskMethodBuilder (et al) and the state machine, including the new interfaces for awaiters. There&amp;#39;s been quite a bit of optimization, although I still see room for a bit more:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When there&amp;#39;s only a single kind of reference type awaiter, the field for storing it could be of that type rather than of type object, removing the need for an execution-time cast &lt;/li&gt;    &lt;li&gt;The &amp;quot;stack&amp;quot; variable could be removed in some cases, and made into a specific type in many others &lt;/li&gt;    &lt;li&gt;With appropriate optimization flags, local variables which aren&amp;#39;t used await expressions could stay local to the state machine instead of being hoisted, and hoisted variables could be aliased in some cases. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;One thing which concerns me slightly is how the C# language specification is going to change - the addition of the new interfaces is definitely going to mean more complexity from this previously &amp;quot;tidy&amp;quot; feature. I&amp;#39;m sure it&amp;#39;s worth it for the sake of efficiency and the like, but part of me sighs at every added tweak.&lt;/p&gt;  &lt;p&gt;So, is this now close to the finished version of async? Only time will tell. I haven&amp;#39;t checked whether dynamic awaitables have finally been introduced... if they have, I&amp;#39;ll put that in the next post.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1807031" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/RJXvEh-Qhn4" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+5/default.aspx">C# 5</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/async/default.aspx">async</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx">Eduasync</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/03/06/eduasync-20-changes-between-the-vs11-preview-and-the-visual-studio-11-beta.aspx</feedburner:origLink></item><item><title>Subtleties in API design - member placement</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/mW6QsW6GpVc/subtleties-in-api-design-member-placement.aspx</link><pubDate>Wed, 29 Feb 2012 17:27:25 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1806600</guid><dc:creator>skeet</dc:creator><slash:comments>38</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1806600</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1806600</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/02/29/subtleties-in-api-design-member-placement.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://noda-time.googlecode.com"&gt;Noda Time&lt;/a&gt; is nearing v1.0, which means I&amp;#39;m spending more time writing documentation than code. It also means reviewing the APIs we&amp;#39;ve got with a critical eye - whether that&amp;#39;s removing extraneous members, adding useful ones, or moving things around. (In particular, writing documentation often suggests where a change would make calling code read more naturally.)&lt;/p&gt;  &lt;p&gt;This post is about one particular section of the API, and the choices available. Although I &lt;em&gt;do&lt;/em&gt; go into some detail around the specific calls involved, that&amp;#39;s just for context... the underlying choices are ones which could be faced when designing any API. I&amp;#39;ve rarely spent as much time thinking about API decisions as I have with Noda Time, so hopefully this will prove interesting to you even if you really don&amp;#39;t care about Noda Time itself as a project.&lt;/p&gt;  &lt;h1&gt;Introduction: time zones, local date/times and zoned date/times - oh my!&lt;/h1&gt;  &lt;p&gt;(Okay, so that&amp;#39;s not quite as snappy as &lt;a href="http://youtu.be/peh61wd-53w?t=42s"&gt;the Judy Garland version&lt;/a&gt;, but hey...)&lt;/p&gt;  &lt;p&gt;The area of API we&amp;#39;re going to focus on is time zones, and converting between &amp;quot;local&amp;quot; date/time values and &amp;quot;zoned&amp;quot; ones. The three types involved are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;LocalDateTime&lt;/strong&gt;: a &amp;quot;local&amp;quot; date and time, with no specific time zone. So, something like &amp;quot;7:30 in the evening on February 27th 2012&amp;quot;. This means different instants in time in different time zones, of course: if you&amp;#39;re arranging a meeting, it&amp;#39;s good enough when the attendees are in the same time zone, but not good enough if you&amp;#39;re meeting with someone on the other side of the world. (A LocalDateTime also has an associated calendar system, but I&amp;#39;m not going to talk about that much in this post.) &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;DateTimeZone&lt;/strong&gt;: a time zone. At its core, this maps &lt;em&gt;any&lt;/em&gt; &amp;quot;instant&amp;quot; in time to an &lt;em&gt;offset&lt;/em&gt; - the difference between UTC and local time in that time zone. The offset changes over time, typically (but not always) due to daylight saving changes. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ZonedDateTime&lt;/strong&gt;: a date and time in a particular time zone, with an offset from UTC to avoid ambiguity in some cases (and for efficiency). This identifies a specific instant in time (simply by subtracting the offset from the local date/time). Conceptually this is equivalent to just maintaining the &amp;quot;instant&amp;quot; value, the time zone, and the calendar system - but it&amp;#39;s generally cleaner to think of it as a &amp;quot;local&amp;quot; value with an offset from UTC. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If those brief descriptions don&amp;#39;t make sense for you at the moment (this sort of thing is quite hard to describe concisely and precisely) you may want to see whether the Noda Time &lt;a href="http://noda-time.googlecode.com/hg/docs/userguide/concepts.html"&gt;user guide &amp;quot;concepts&amp;quot; page&lt;/a&gt; helps.&lt;/p&gt;  &lt;h3&gt;The API task: mapping from { LocalDateTime, DateTimeZone } to ZonedDateTime&lt;/h3&gt;  &lt;p&gt;It&amp;#39;s easy to get from a ZonedDateTime to a LocalDateTime - you can just use the LocalDateTime property. The difficult bit is the other way round. We obviously want to be able to create a ZonedDateTime from the combination of a LocalDateTime and a DateTimeZone, but the question is where to put this functionality. Three options suggest themselves:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A static method (or constructor) in ZonedDateTime which takes both the time zone and the local date/time as arguments &lt;/li&gt;    &lt;li&gt;An instance method on LocalDateTime which just takes the time zone as an argument &lt;/li&gt;    &lt;li&gt;An instance method on DateTimeZone which just takes the local date/time as an argument &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It gets more complicated though - we&amp;#39;re not really talking about &lt;em&gt;one&lt;/em&gt; operation here, but potentially several. Although the mapping from instant to offset is unambiguous in DateTimeZone, the mapping from LocalDateTime to offset is &lt;em&gt;not &lt;/em&gt;straightforward. There can be 0, 1 or 2 possible results. For example, in the America/Los_Angeles time zone the clocks go forward from 2am to 3am on Sunday March 11th 2012, and go back from 2am to 1am on Sunday 4th November 2012. That means:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The mapping from local date/time to offset at 7.30pm on February 27th 2012 is unambiguous: it&amp;#39;s definitely -8 hours (L.A. is 8 hours &lt;em&gt;behind&lt;/em&gt; UTC). &lt;/li&gt;    &lt;li&gt;The mapping at 2.30am on March 11th 2012 is &lt;em&gt;impossible&lt;/em&gt;: at 2am the clocks were put forward to 3am, so 2.30am simply never occurs. &lt;/li&gt;    &lt;li&gt;The mapping at 2.30am on November 4th 2012 is &lt;em&gt;ambiguous&lt;/em&gt;: it happens once &lt;em&gt;before&lt;/em&gt; the clocks go back at 3am, and once &lt;em&gt;afterwards&lt;/em&gt;. The offset is either -7 or -8 hours, depending on which occurrence you mean. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;When mapping a local time to &amp;quot;global&amp;quot; time, this is something you should really think about. Most APIs obscure the issue, but one of the purposes of Noda Time is to &lt;em&gt;force&lt;/em&gt; developers to think about issues which they should be aware of. This one is particularly insidious in that it&amp;#39;s the kind of problem which is &lt;em&gt;much&lt;/em&gt; more likely to arise when you&amp;#39;re asleep than during daylight hours - so it&amp;#39;s unlikely to be found during manual testing. (Ditto the day of week - most time zones have daylight saving transitions early on a Sunday morning.)&lt;/p&gt;  &lt;p&gt;So, Noda Time exposes four ways of mapping a LocalDateTime and DateTimeZone to a ZonedDateTime:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Exact: if there&amp;#39;s a single mapping, return it. Otherwise, throw an exception. &lt;/li&gt;    &lt;li&gt;Earlier: if there&amp;#39;s a single mapping, return it. If there&amp;#39;s more than one, return the earlier one. If the time is skipped, throw an exception. &lt;/li&gt;    &lt;li&gt;Later: if there&amp;#39;s a single mapping, return it. If there&amp;#39;s more than one, return the later one. If the time is skipped, throw an exception. &lt;/li&gt;    &lt;li&gt;All information: find out all the information relevant to mapping the given local value - how many matches there are, what they would be, what the time zone information is for each mapping, etc. The caller can then do what they want. &lt;/li&gt; &lt;/ul&gt;  &lt;h1&gt;Options available&lt;/h1&gt;  &lt;p&gt;The question is &lt;em&gt;how&lt;/em&gt; we expose these operations. Let&amp;#39;s look at some options, then discuss the pros and cons.&lt;/p&gt;  &lt;h3&gt;Option 1: methods on LocalDateTime&lt;/h3&gt;  &lt;p&gt;A lot of Noda Time is designed to be &amp;quot;fluent&amp;quot; so it makes a certain amount of sense to be able to take a LocalDateTime, perform some arithmetic on it, then convert it to a ZonedDateTime, then (say) format it. So we could have something like:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;var zoned = local.InZone(zone); // implicitly exact &lt;/li&gt;    &lt;li&gt;var zoned = local.InZoneOrEarlier(zone); &lt;/li&gt;    &lt;li&gt;var zoned = local.InZoneOrLater(zone); &lt;/li&gt;    &lt;li&gt;var mapping = local.MapToZone(zone); &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Option 2: methods on DateTimeZone&lt;/h3&gt;  &lt;p&gt;All the calculations involved are really about the time zone - the local date/time value is just a simple value as far as most of this is concerned. So we can put the methods on DateTimeZone instead:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;var zoned = zone.AtExactly(local); &lt;/li&gt;    &lt;li&gt;var zoned = zone.AtEarlier(local); &lt;/li&gt;    &lt;li&gt;var zoned = zone.AtLater(local); &lt;/li&gt;    &lt;li&gt;var mapping = zone.MapLocalDateTime(local); &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Option 3: methods (or constructors) on ZonedDateTime&lt;/h3&gt;  &lt;p&gt;Maybe we consider the two inputs to be fairly equal, but the result type is more important:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;var zoned = ZonedDateTime.FromLocal(zone, local); &lt;/li&gt;    &lt;li&gt;var zoned = ZonedDateTime.FromLocalOrEarlier(zone, local); &lt;/li&gt;    &lt;li&gt;var zoned = ZonedDateTime.FromLocalOrLater(zone, local); &lt;/li&gt;    &lt;li&gt;var mapping = ZoneLocalMapping.FromLocal(local) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(I&amp;#39;m not terribly happy about the names here; there could be better ones of course.)&lt;/p&gt;  &lt;h3&gt;Variation a: any of the above options, but with an enum for ambiguity resolution&lt;/h3&gt;  &lt;p&gt;We don&amp;#39;t really need four methods on any of these APIs; the first three only differ by how they handle ambiguity (the situation where a particular local date/time occurs twice). We could use an enum to represent that choice instead:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;var zoned = local.InZone(zone, ZoneAmbiguityResolver.Error); &lt;/li&gt;    &lt;li&gt;var zoned = local.InZone(zone, ZoneAmbiguityResolver.Earlier); &lt;/li&gt;    &lt;li&gt;var zoned = local.InZone(zone, ZoneAmbiguityResolver.Later); &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(Or a &amp;quot;smart enum&amp;quot; with behaviour, if we wanted. A normal class type with methods etc, but only a restricted set of valid values.)&lt;/p&gt;  &lt;h3&gt;Variation b: always go via the mapping result&lt;/h3&gt;  &lt;p&gt;Given that we already have the idea of getting the full mapping results, we can reduce the API to just &lt;em&gt;one&lt;/em&gt; method to return the mapping information, and then put extra methods on that:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;var zoned = local.MapInZone(zone).SingleMatch; &lt;/li&gt;    &lt;li&gt;var zoned = local.MapInZone(zone).SingleOrEarlier; &lt;/li&gt;    &lt;li&gt;var zoned = local.MapInZone(zone).SingleOrLater; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(Again, the names aren&amp;#39;t fixed in stone, and the second part could be methods instead of properties if we wanted.)&lt;/p&gt;  &lt;h3&gt;Variation c: return a sequence of results&lt;/h3&gt;  &lt;p&gt;If we return a sequence with 0, 1 or 2 ZonedDateTime values, the user can just use LINQ to get the one they want. Again, this can apply wherever we decide to put the method:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;var zoned = zone.At(local).Single(); &lt;/li&gt;    &lt;li&gt;var zoned = zone.At(local).First(); &lt;/li&gt;    &lt;li&gt;var zoned = zone.At(local).Last(); &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So, it looks like we effectively have two mostly-orthogonal decisions here:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Where to &amp;quot;start&amp;quot; the conversion - the target type for the method call &lt;/li&gt;    &lt;li&gt;How to represent the multiple options &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We&amp;#39;ll consider them separately.&lt;/p&gt;  &lt;h1&gt;Regarding the &amp;quot;source&amp;quot; type&lt;/h1&gt;  &lt;p&gt;To start with, I&amp;#39;ll reveal my bias: the existing implementation is option 2 (four methods on DateTimeZone). This was after a small amount of debate on the Noda Time mailing list, and this was the most relevant bit of the discussion:&lt;/p&gt;  &lt;p&gt;Me (&lt;em&gt;before&lt;/em&gt; going with the current implementation):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;It feels a little odd to me to use the zone as the principal class here - just in terms of usability. It makes total sense in terms of the logic, but I tend to think of having a LocalDateTime first, and then converting &lt;em&gt;that&lt;/em&gt; to use a particular zone - it&amp;#39;s not an operation which feels like it acts on the zone itself.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;David N:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I actually feel the opposite: asking a DateTimeZone how a particular LocalDateTime would be represented in that zone feels natural, while asking the LocalDateTime how it would be represented in a zone feels odd. The zone is a first-class entity, with identity and behavior; the LocalDateTime is just a set of values. Why would the LocalDateTime be expected to know how it is represented in a particular zone?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Even though I replied to that in a &amp;quot;maybe&amp;quot; kind of tone, the argument basically convinced me. The trouble is, a colleague was then &lt;em&gt;surprised&lt;/em&gt; when he read the documentation around calendar arithmetic and conversions. Surprising users is pretty much a cardinal sin when it comes to API design - and although in this case it was the relatively harmless sort of surprise (&amp;quot;I can&amp;#39;t find the member I want in A; oh, it turns out it&amp;#39;s in B&amp;quot;) rather than a &lt;em&gt;behavioural&lt;/em&gt; surprise (&amp;quot;I thought it would do X, but instead it does Y&amp;quot;) it&amp;#39;s still bad news. I should reveal my colleague&amp;#39;s bias too - he has experience of &lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time&lt;/a&gt;, where the relevant call is &lt;a href="http://joda-time.sourceforge.net/api-release/org/joda/time/LocalDateTime.html#toDateTime(org.joda.time.DateTimeZone)"&gt;LocalDateTime.toDateTime(DateTimeZone)&lt;/a&gt;. (There &lt;em&gt;are&lt;/em&gt; calls in DateTimeZone itself, but they&amp;#39;re lower-level.)&lt;/p&gt;  &lt;p&gt;We&amp;#39;ve discussed this a fair amount (leading to this blog post) and so far we&amp;#39;ve concluded that it really depends on how you &lt;em&gt;think&lt;/em&gt; about time zones. As a Noda Time user, would you consider them to be rich objects with complex behaviour, or would you think of them as mere &amp;quot;tokens&amp;quot; to be passed around and used without much direct interaction? The two ways of viewing the type aren&amp;#39;t necessarily in conflict - I&amp;#39;ve &lt;em&gt;deliberately&lt;/em&gt; designed CalendarSystem to hide its (fairly ugly) innards. There are a few public instance members, but most are internal. But what about time zones?&lt;/p&gt;  &lt;p&gt;There&amp;#39;s an argument to be made for &lt;em&gt;educating&lt;/em&gt; Noda Time users to think about time zones as more complex beasts than just tokens, and I&amp;#39;m happy to do that in other areas (such as choosing which type to use in the first place) but here it feels like it&amp;#39;s one step too far. On the other hand, I don&amp;#39;t want to stifle users who &lt;em&gt;are&lt;/em&gt; thinking of DateTimeZone in that way. In the mailing list thread, David also expressed a dislike for the approach of including functionality in multiple places - and to a certain extent I agree (one of the things I &lt;em&gt;dislike&lt;/em&gt; about its API is that it lets you do just about anything with anything)... but in this case it feels like it&amp;#39;s justified.&lt;/p&gt;  &lt;p&gt;Regardless of how you&amp;#39;re thinking about DateTimeZone, it&amp;#39;s more likely that you&amp;#39;re going to want to &lt;em&gt;use&lt;/em&gt; a LocalDateTime value which is the result of some other expression, and then apply some &amp;quot;constant&amp;quot; zone to it, then potentially keep going. If you think about a LINQ-style pipeline of operations, the part that varies in the conversion is much more likely to be the LocalDateTime than the time zone. As such, a method on LocalDateTime allows for a more fluent calling style:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; zoned = parseResult.Value     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .PlusMonths(1)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .InZone(LondonTimeZone); &lt;/div&gt;  &lt;p&gt;versus:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; zoned = LondonTimeZone.AtExactly(parseResult.Value.PlusMonths(1)); &lt;/div&gt;  &lt;p&gt;Or to keep the code order the same as the execution order:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; local = parseResult.Value.PlusMonths(1);     &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; zoned = LondonTimeZone.AtExactly(local); &lt;/div&gt;  &lt;p&gt;Obviously the effects become more noticeable the more operations you perform. Personally I&amp;#39;m happy with either the first or third approach - although it&amp;#39;s worth being aware that either of the first &lt;em&gt;two&lt;/em&gt; have the advantage of being one expression, and therefore easy to use when assigning a static readonly field or something similar.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m &lt;em&gt;reasonably&lt;/em&gt; happy with having one method on each type, or possibly two (MapLocalDateTime and At*) on DateTimeZone and one (just InZone) on LocalDateTime. I &lt;em&gt;really&lt;/em&gt; don&amp;#39;t like the idea of having four methods on DateTimeZone and three methods on LocalDateTime. So, let&amp;#39;s consider the different variations which cut down the number of methods required.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Expressing &amp;quot;exactly,&amp;quot; &amp;quot;earlier,&amp;quot; and &amp;quot;later&amp;quot; in one method&lt;/h1&gt;  &lt;p&gt;This is essentially a discussion of the &amp;quot;variations&amp;quot; above. Just to recap, the possibilities we&amp;#39;ve come up with are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Add another parameter to the method to indicate how to handle ambiguities (or impossibilities) - just return a ZonedDateTime &lt;/li&gt;    &lt;li&gt;Return a value of a different type (e.g. ZoneLocalMapping) which can be used to get at all the information you could want &lt;/li&gt;    &lt;li&gt;Return a sequence of possible ZonedDateTime values, expecting the caller to probably use LINQ&amp;#39;s First/Last/Single/FirstOrDefault etc to get at the value they want &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The last of these is the only one which gives an easy way of handling the extreme corner case of a local time occurring &lt;em&gt;more&lt;/em&gt; than twice - for example, a time zone which goes back one hour at 2am (to 1am) and then goes back another two hours at 3am. I think it&amp;#39;s reasonable to dismiss this corner case; however mad time zones can be, I haven&amp;#39;t seen anything &lt;em&gt;quite&lt;/em&gt; that crazy yet.&lt;/p&gt;  &lt;p&gt;At the time of the original discussion, Noda Time was targeting .NET 2.0, which was one reason for not going with the final option here - we couldn&amp;#39;t guarantee that LINQ would be available. Now, Noda Time is targeting .NET 3.5 in order to use TimeZoneInfo, but it still doesn&amp;#39;t feel like an ideal fit:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Returning a sequence doesn&amp;#39;t give information about (say) the two zone intervals &amp;quot;surrounding&amp;quot; a gap &lt;/li&gt;    &lt;li&gt;A sequence may be surprising to users who expect just a single value &lt;/li&gt;    &lt;li&gt;The exceptions thrown by First, Single etc when their expectations aren&amp;#39;t met are very domain-neutral; we can give more information &lt;/li&gt;    &lt;li&gt;FirstOrDefault will return the default value for ZonedDateTime in the case of ambiguity. That would be unfortunate, as ZonedDateTime is a value type, and its default value is actually somewhat unhelpful. (It has a null calendar system, effectively. There&amp;#39;s not a lot we can do about this, but that&amp;#39;s a post for another day.) We could make it a sequence of Nullable&amp;lt;ZonedDateTime&amp;gt; and guarantee that any values in it are actually non-null, but that&amp;#39;s really straining things. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Putting these together, there are enough negative points to this idea that I&amp;#39;m happy to rule it out. But what about the first two?&lt;/p&gt;  &lt;p&gt;The first has the advantage that the caller only needs to make a single method call, effectively passing in a &amp;quot;magic token&amp;quot; (the ambiguity resolver) which they don&amp;#39;t &lt;em&gt;really&lt;/em&gt; need to understand. On the other hand, if they want more information, they&amp;#39;ll have to call a different method - and I&amp;#39;m not really sure we want to encourage too much of this &amp;quot;magic token&amp;quot; behaviour.&lt;/p&gt;  &lt;p&gt;The second has three disadvantages, all fairly slight:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The user may initially expect the result of a method mapping a LocalDateTime to a ZonedDateTime to &lt;em&gt;be&lt;/em&gt; a ZonedDateTime... what&amp;#39;s this extra intermediate result doing? This is &amp;quot;only&amp;quot; a matter of user education, and it&amp;#39;s pretty discoverable. It&amp;#39;s an extra concept the user needs to understand, but it&amp;#39;s a &lt;em&gt;good&lt;/em&gt; concept to understand. &lt;/li&gt;    &lt;li&gt;Calling two methods or a method and a property (e.g. zone.MapLocalDateTime(localDateTime).Earlier) may end up being slightly more long-winded than a single method call. I can&amp;#39;t get excited about this. &lt;/li&gt;    &lt;li&gt;We have to allocate an extra object for the mapping, even when we know it&amp;#39;s unique. Usually, this object will become eligible for garbage collection immediately. We &lt;em&gt;could&lt;/em&gt; make it a struct, but I don&amp;#39;t think it&amp;#39;s a natural value type - I&amp;#39;d rather trust that allocating objects in gen0 is pretty cheap. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;With the second method, we can replace &lt;em&gt;all&lt;/em&gt; the existing methods in DateTimeZone with a single one (or rather, just remove the AtXyz methods, leaving MapLocalDateTime). We can then create pleasantly-named methods on ZoneLocalMapping (which isn&amp;#39;t quite right for this purpose at the moment).&lt;/p&gt;  &lt;h1&gt;Conclusion&lt;/h1&gt;  &lt;p&gt;This has been an interesting thought experiment for me, and it&amp;#39;s suggested some changes I &lt;em&gt;will&lt;/em&gt; be applying before v1. We&amp;#39;ll see how they pan out. If you want to follow them, look for relevant &lt;a href="http://code.google.com/p/noda-time/source/list"&gt;source code changes&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The important points I&amp;#39;ve been thinking about are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;What would a new user &lt;em&gt;expect&lt;/em&gt; to be available? If they haven&amp;#39;t read any documentation, what are they likely to try? &lt;/li&gt;    &lt;li&gt;What &lt;em&gt;should&lt;/em&gt; the user know about? Where there are important decisions to make, how can we provide guidance? &lt;/li&gt;    &lt;li&gt;What would an &lt;em&gt;experienced&lt;/em&gt; user (who is already thinking about the Noda Time concepts in the way that we want to encourage) expect to be available? &lt;/li&gt;    &lt;li&gt;Where does the balance lie between providing a &amp;quot;too crowded&amp;quot; API (with lots of different ways of achieving the same thing) and a &amp;quot;sparse&amp;quot; API (where there&amp;#39;s always one way of achieving a goal, but it may not be the most convenient one for your situation) &lt;/li&gt;    &lt;li&gt;How does our choice fit in with other technologies? For example, the final &amp;quot;variation&amp;quot; seems like it plays nicely with LINQ at first - but a few subtleties make it a worse fit than it might seem. &lt;/li&gt;    &lt;li&gt;How does this affect performance? (Performance is important in Noda Time - but there would have to be a &lt;em&gt;significant&lt;/em&gt; performance problem for me to deviate from an elegant solution.) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So, any other thoughts? Did we miss some options? What other factors should we have taken into consideration?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1806600" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/mW6QsW6GpVc" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Design/default.aspx">Design</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/02/29/subtleties-in-api-design-member-placement.aspx</feedburner:origLink></item><item><title>Currying vs partial function application</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/jeibq6H-CdU/currying-vs-partial-function-application.aspx</link><pubDate>Mon, 30 Jan 2012 18:32:06 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1805414</guid><dc:creator>skeet</dc:creator><slash:comments>35</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1805414</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1805414</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/01/30/currying-vs-partial-function-application.aspx#comments</comments><description>&lt;p&gt;This is a slightly odd post, and before you read it you should probably put yourself into one of three buckets:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Someone who doesn&amp;#39;t care too much about functional programming, and finds higher order functions tricky: feel free to skip this post entirely. &lt;/li&gt;    &lt;li&gt;Someone who knows all about functional programming, and already knows the difference between currying and partial function application: please read this post carefully and post comments about any inaccuracies you find. (Yes, the CAPTCHA is broken on Chrome; sorry.) &lt;/li&gt;    &lt;li&gt;Someone who &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; know much about functional programming yet, but is interested to learn more: please take this post with a pinch of salt, and read the comments carefully. Read other articles by more experienced developers for more information. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Basically, I&amp;#39;ve been aware for a while that some people use the terms &lt;em&gt;currying&lt;/em&gt; and &lt;em&gt;partial function application&lt;/em&gt; somewhat interchangably, when they shouldn&amp;#39;t. It&amp;#39;s one of those topics (like monads) which I feel I understand to some extent, and I&amp;#39;ve decided that the best way of making sure I understand it is to try to write about it. If it helps the topic become more accessible to other developers, so much the better.&lt;/p&gt;  &lt;h3&gt;This post contains no Haskell&lt;/h3&gt;  &lt;p&gt;Almost every explanation I&amp;#39;ve ever seen of either topic has given examples in a &amp;quot;proper&amp;quot; functional language, typically Haskell. I have absolutely nothing against Haskell, but I typically find it easier to understand examples in a programming language I understand. I also find it &lt;em&gt;much&lt;/em&gt; easier to &lt;em&gt;write&lt;/em&gt; examples in a program language I understand, so all the examples in this post are going to be in C#. In fact, it&amp;#39;s all available in a &lt;a href="http://pobox.com/~skeet/csharp/blogfiles/Curry.cs"&gt;single file&lt;/a&gt; - that includes all of the examples, admittedly with a few variables renamed. Just compile and run.&lt;/p&gt;  &lt;p&gt;C# isn&amp;#39;t really a functional language - I know just about enough to understand that delegates aren&amp;#39;t really a proper substitute for first class functions. However, they&amp;#39;re good enough to demonstrate the principles involved.&lt;/p&gt;  &lt;p&gt;While it&amp;#39;s possible to demonstrate currying and partial function application using a function (method) taking a very small number of parameters, I&amp;#39;ve chosen to use 3 for clarity. Although my methods to perform the currying and partial function application will be generic (so all the types of parameters and return value are arbitrary) I&amp;#39;m using a simple function for demonstration purposes:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; SampleFunction(&lt;span class="ValueType"&gt;int&lt;/span&gt; a, &lt;span class="ValueType"&gt;int&lt;/span&gt; b, &lt;span class="ValueType"&gt;int&lt;/span&gt; c)&amp;#160; &lt;br /&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;.Format(&lt;span class="String"&gt;&amp;quot;a={0}; b={1}; c={2}&amp;quot;&lt;/span&gt;, a, b, c);&amp;#160; &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;So far, so simple. There&amp;#39;s &lt;em&gt;nothing tricky&lt;/em&gt; about that method, so don&amp;#39;t look for anything surprising.&lt;/p&gt;  &lt;h3&gt;What&amp;#39;s it all about?&lt;/h3&gt;  &lt;p&gt;Both currying and partial function application are about converting one sort of function to another. We&amp;#39;ll use delegates as an approximation to functions, so if we want to treat the method SampleFunction as a value, we can write:&lt;/p&gt;  &lt;div class="code"&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; function = SampleFunction; &lt;/div&gt;  &lt;p&gt;This single line is useful for two reasons:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Assigning the value to a variable hammers home the point that it really is a value. A delegate instance is an object much like any other, and the value of the function variable is a reference just like any other. &lt;/li&gt;    &lt;li&gt;Method group conversions (using just the name of the method as a way of creating a delegate) doesn&amp;#39;t work terribly nicely with type inference when calling a generic method. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;We can already call the function using three arguments with no further work:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result = function(1, 2, 3); &lt;/div&gt;  &lt;p&gt;Or equivalently:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result = function.Invoke(1, 2, 3); &lt;/div&gt;  &lt;p&gt;(The C# compiler just converts the shorthand of the first form to the second. The IL emitted will be the same.)&lt;/p&gt;  &lt;p&gt;That&amp;#39;s fine if we&amp;#39;ve got all the arguments available at the same time, but what if we haven&amp;#39;t? To give a concrete (if somewhat contrived) example, suppose we have a logging function with three parameters (source, severity, message) and within a single class (which I&amp;#39;ll call BusinessLogic for the moment) we always want to use the same value for the &amp;quot;source&amp;quot; parameter, and we&amp;#39;d like to be able to log easily everywhere in the class specifying just the severity and message. We have a few options:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Create an adapter class which takes the log function (or more generally a logging object) and the &amp;quot;source&amp;quot; value in its constructor, stashes both in instance variables, and exposes a method with two parameters. That method just delegates to the stashed logger, using the source it&amp;#39;s remembered to supply the first argument to the three-parameter method. In BusinessLogic we create an instance of the adapter class, and stash a reference in an instance variable - then just call the two-parameter method everywhere we need to. This is probably overkill if we only need the adapter from BusinessLogic, but it&amp;#39;s reusable... so long as we&amp;#39;re trying to adapt the same logging function. &lt;/li&gt;    &lt;li&gt;Store the original logger in our BusinessLogic class, but create a helper method with two parameters. This can hard-code the value used for the &amp;quot;source&amp;quot; parameter in one place (the helper method). If we need to do this in several places, it gets annoying. &lt;/li&gt;    &lt;li&gt;Use a more general functional programming approach - probably &lt;em&gt;partial function application&lt;/em&gt; in this case. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I&amp;#39;m deliberately ignoring the discrepancy between holding a reference to &amp;quot;the logger&amp;quot; and holding a reference to &amp;quot;the logging function&amp;quot;. Obviously there&amp;#39;s a significant difference if we need to use more than one function from the logging class, but for the purposes of thinking about currying and partial function application, we&amp;#39;ll just think of &amp;quot;a logger&amp;quot; as &amp;quot;a function taking three parameters&amp;quot; (like our sample function).&lt;/p&gt;  &lt;p&gt;Now that I&amp;#39;ve given the slightly-real-world concrete example for a bit of motivation, I&amp;#39;m going to ignore it for the rest of the post, and just talk about our sample function. I don&amp;#39;t want to write a whole BusinessLogic class which pretends to do something useful; I&amp;#39;m sure you can perform the appropriate mental conversion from &amp;quot;the sample function&amp;quot; to &amp;quot;something I might actually want to do&amp;quot;.&lt;/p&gt;  &lt;h3&gt;Partial Function Application&lt;/h3&gt;  &lt;p&gt;The purpose of partial function application is to take a function with N parameters and a value for one of those parameters, and return a function with N-1 parameters, such that calling the result will assemble all the required values appropriately (the 1 argument given to the partial application operation itself, and the N-1 arguments given to the returned function). So in code form, these two calls should be equivalent for our 3-parameter method:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Normal call &lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result1 = function(1, 2, 3);     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Call via partial application &lt;/span&gt;    &lt;br /&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; partialFunction = ApplyPartial(function, 1);&amp;#160; &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result2 = partialFunction(2, 3); &lt;/div&gt;  &lt;p&gt;In this case I&amp;#39;ve implemented partial application with a single parameter, and chosen the first one - you &lt;em&gt;could&lt;/em&gt; write an ApplyPartial method which took more arguments to apply, or which used them somewhere else in the final function execution. I believe that picking off parameters one at a time, from the start, is the most conventional approach.&lt;/p&gt;  &lt;p&gt;Thanks to anonymous functions (a lambda expression in this case, but an anonymous method wouldn&amp;#39;t be much more verbose), the implementation of ApplyPartial is simple:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;static&lt;/span&gt; Func&amp;lt;T2, T3, TResult&amp;gt; ApplyPartial&amp;lt;T1, T2, T3, TResult&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (Func&amp;lt;T1, T2, T3, TResult&amp;gt; function, T1 arg1)&amp;#160; &lt;br /&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; (b, c) =&amp;gt; function(arg1, b, c);&amp;#160; &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The generics make the method look more complicated than it really is. Note that the lack of higher order types in C# means that you&amp;#39;d need a method like this for &lt;em&gt;every&lt;/em&gt; delegate you wanted to use - if you wanted a version for a function which started with four parameters, you&amp;#39;d need an ApplyPartial&amp;lt;T1, T2, T3, T4, TResult&amp;gt; method etc. You&amp;#39;d probably also want a parallel set of methods for the Action delegate family.&lt;/p&gt;  &lt;p&gt;The final thing to note is that assuming we had all of these methods, we could perform partial function application again - even potentially down to a parameterless function if we wanted, like this:&lt;/p&gt;  &lt;div class="code"&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; partial1 = ApplyPartial(function, 1);&amp;#160; &lt;br /&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; partial2 = ApplyPartial(partial1, 2);&amp;#160; &lt;br /&gt;Func&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; partial3 = ApplyPartial(partial2, 3);&amp;#160; &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result = partial3(); &lt;/div&gt;  &lt;p&gt;Again, only the final line would actually invoke the original function.&lt;/p&gt;  &lt;p&gt;Okay, so that&amp;#39;s partial function application. That&amp;#39;s &lt;em&gt;relatively&lt;/em&gt; straightforward. Currying is slightly harder to get your head round, in my view.&lt;/p&gt;  &lt;h3&gt;Currying&lt;/h3&gt;  &lt;p&gt;Whereas partial function application converts a function with N parameters into a function with N-1 parameters by applying one argument, currying effectively decomposes the function into functions taking a single parameter. We don&amp;#39;t pass any arguments into the Curry method itself:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Curry(f) returns a function f1 such that... &lt;/li&gt;    &lt;li&gt;f1(a) returns a function f2 such that... &lt;/li&gt;    &lt;li&gt;f2(b) returns a function f3 such that... &lt;/li&gt;    &lt;li&gt;f3(c) invokes f(a, b, c) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(Again, note that this is specific to our three-parameter function - but hopefully it&amp;#39;s obvious how it would extend to other signatures.)&lt;/p&gt;  &lt;p&gt;To give our &amp;quot;equivalence&amp;quot; example again, we can write:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Normal call &lt;/span&gt;    &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result1 = function(1, 2, 3);     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Call via currying &lt;/span&gt;    &lt;br /&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt; f1 = Curry(function);&amp;#160; &lt;br /&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;&amp;gt; f2 = f1(1);&amp;#160; &lt;br /&gt;Func&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt; f3 = f2(2);&amp;#160; &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result2 = f3(3);     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Or to do make all the calls together... &lt;/span&gt;    &lt;br /&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; curried = Curry(function);&amp;#160; &lt;br /&gt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; result3 = curried(1)(2)(3); &lt;/div&gt;  &lt;p&gt;The difference between the latter examples shows one reason why functional languages often have good type inference and compact representations of function types: that declaration of f1 is pretty fearsome.&lt;/p&gt;  &lt;p&gt;Now that we know what the Curry method is meant to do, it&amp;#39;s actually surprisingly simple to implement. Indeed, all we need to do is translate the bullet points above into lambda expressions. It&amp;#39;s a thing of beauty:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;static&lt;/span&gt; Func&amp;lt;T1, Func&amp;lt;T2, Func&amp;lt;T3, TResult&amp;gt;&amp;gt;&amp;gt; Curry&amp;lt;T1, T2, T3, TResult&amp;gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; (Func&amp;lt;T1, T2, T3, TResult&amp;gt; function)&amp;#160; &lt;br /&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; a =&amp;gt; b =&amp;gt; c =&amp;gt; function(a, b, c);&amp;#160; &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;If you want to add some brackets to make it clearer for you, feel free - personally I think it just adds clutter. Either way, we get what we want. (It&amp;#39;s worth thinking about how annoying it would be to write that without lambda expressions or anonymous methods. Not &lt;em&gt;hard&lt;/em&gt;, just annoying.)&lt;/p&gt;  &lt;p&gt;So that&amp;#39;s currying. I think. Maybe.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;I can&amp;#39;t say I&amp;#39;ve ever knowingly used currying, whereas I suspect some bits of &lt;a href="http://noda-time.googlecode.com"&gt;Noda Time&lt;/a&gt;&amp;#39;s text parsing effectively use partial functional application. (If anyone really wants me to dig in and check, I&amp;#39;ll do so.)&lt;/p&gt;  &lt;p&gt;I really hope I&amp;#39;ve got the difference between them right here - it &lt;em&gt;feels&lt;/em&gt; right, in that the two are clearly related, but also quite distinct. Now that we&amp;#39;ve reached the end, think about how that difference manifests itself when there are only two parameters, and hopefully you&amp;#39;ll see why I chose to use three :)&lt;/p&gt;  &lt;p&gt;My gut feeling is that currying is a more useful concept in an academic context, whereas partial functional application is more useful in practice. However, that&amp;#39;s the gut feeling of someone who hasn&amp;#39;t really used a functional language in anger. If I ever &lt;em&gt;really&lt;/em&gt; get round to using F#, maybe I&amp;#39;ll do a follow-up post. For now, I&amp;#39;m hoping that my trusty smart readers can provide useful thoughts for others.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1805414" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/jeibq6H-CdU" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/01/30/currying-vs-partial-function-application.aspx</feedburner:origLink></item><item><title>Eduasync part 19: ordering by completion, ahead of time...</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/t0SgYtV4iDA/eduasync-part-19-ordering-by-completion-ahead-of-time.aspx</link><pubDate>Mon, 16 Jan 2012 22:22:43 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1804970</guid><dc:creator>skeet</dc:creator><slash:comments>18</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1804970</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1804970</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/01/16/eduasync-part-19-ordering-by-completion-ahead-of-time.aspx#comments</comments><description>&lt;p&gt;Today&amp;#39;s post involves the &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FMagicOrdering"&gt;MagicOrdering project&lt;/a&gt; in source control (project 28).&lt;/p&gt;  &lt;p&gt;When I wrote &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/11/22/eduasync-part-16-example-of-composition-majority-voting.aspx"&gt;part 16 of Eduasync&lt;/a&gt;, showing composition in the form of majority voting, one reader mailed me a &lt;em&gt;really&lt;/em&gt; interesting suggestion. We don&amp;#39;t really need to wait for &lt;em&gt;any&lt;/em&gt; of the tasks to complete on each iteration of the loop - we only need to wait for the &lt;em&gt;next&lt;/em&gt; task to complete. Now that sounds impossible - sure, it&amp;#39;s great if we know the completion order of the tasks, but half the point of asynchrony is that many things can be happening at once, and we don&amp;#39;t know when they&amp;#39;ll complete. However, it&amp;#39;s not as silly as it sounds.&lt;/p&gt;  &lt;p&gt;If you give me a collection of tasks, I&amp;#39;ll give you back another collection of tasks which will return the same results - but I&amp;#39;ll order them so that the first returned task will have the same result as whichever of your original tasks completes first, and the second returned task will have the same result as whichever of your original tasks completes second, and so on. They won&amp;#39;t be the &lt;em&gt;same&lt;/em&gt; tasks as you gave me, reordered - but they&amp;#39;ll be tasks with the same results. I&amp;#39;ll propagate cancellation, exceptions and so on.&lt;/p&gt;  &lt;p&gt;It still sounds impossible... until you realize that I don&amp;#39;t have to associate one of my returned tasks with one of your original tasks &lt;em&gt;until it has completed&lt;/em&gt;. Before anything has completed, all the tasks look the same. The trick is that as soon as I see one of your tasks complete, I can fetch the result and propagate it to the first of the tasks I&amp;#39;ve returned to you, using TaskCompletionSource&amp;lt;T&amp;gt;. When the second of your tasks completes, I propagate the result to the second of the returned tasks, etc. This is all quite easy using &lt;a href="http://msdn.microsoft.com/en-us/library/dd235663.aspx"&gt;Task&amp;lt;T&amp;gt;.ContinueWith&lt;/a&gt; - barring a few caveats I&amp;#39;ll mention later on.&lt;/p&gt;  &lt;p&gt;Once we&amp;#39;ve built a method to do this, we can then &lt;em&gt;really easily&lt;/em&gt; build a method which is the async equivalent of &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.foreach.aspx"&gt;Parallel.ForEach&lt;/a&gt; (and indeed you could write multiple methods for the various overloads). This will execute a specific action on each task in turn, as it completes... it&amp;#39;s &lt;em&gt;like&lt;/em&gt; repeatedly calling &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenany(v=vs.110).aspx"&gt;Task.WhenAny&lt;/a&gt;, but we only actually need to wait for one task at a time, because we know that the first task in our &amp;quot;completion ordered&amp;quot; collection will be the first one to complete (duh).&lt;/p&gt;  &lt;h3&gt;Show me the code!&lt;/h3&gt;  &lt;p&gt;Enough description - let&amp;#39;s look at how we&amp;#39;ll demonstrate both methods, and then how we implement them.&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt; Task PrintDelayedRandomTasksAsync()     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Random rng = &lt;span class="Keyword"&gt;new&lt;/span&gt; Random();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; values = Enumerable.Range(0, 10).Select(_ =&amp;gt; rng.Next(3000)).ToList();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Initial order: {0}&amp;quot;&lt;/span&gt;, &lt;span class="ReferenceType"&gt;string&lt;/span&gt;.Join(&lt;span class="String"&gt;&amp;quot; &amp;quot;&lt;/span&gt;, values));     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; tasks = values.Select(DelayAsync);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; ordered = OrderByCompletion(tasks);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;In order of completion:&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; ForEach(ordered, Console.WriteLine);     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// Returns a task which delays (asynchronously) by the given number of milliseconds,&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// then return that same number back.&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt; Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; DelayAsync(&lt;span class="ValueType"&gt;int&lt;/span&gt; delayMillis)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; TaskEx.Delay(delayMillis);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; delayMillis;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The idea is that we&amp;#39;re going to create 10 tasks which each just wait for some random period of time, and return the same time period back. We&amp;#39;ll create them in any old order - but obviously they should complete in (at least roughly) the same order as the returned numbers.&lt;/p&gt;  &lt;p&gt;Once we&amp;#39;ve created the collection of tasks, we&amp;#39;ll call OrderByCompletion to create a &lt;em&gt;second&lt;/em&gt; collection of tasks, returning the same results but this time in completion order - so ordered.ElementAt(0) will be the first task to complete, for example.&lt;/p&gt;  &lt;p&gt;Finally, we call ForEach and pass in the ordered task collection, along with Console.WriteLine as the action to take with each value. We await the resulting Task to mimic blocking until the foreach loop has finished. Note that we &lt;em&gt;could&lt;/em&gt; make this a non-async method and just return the task returned by ForEach, given that that&amp;#39;s our only await expression and it&amp;#39;s right at the end of the method. This would be marginally faster, too - there&amp;#39;s no need to build an extra state machine. See &lt;a href="http://msdn.microsoft.com/en-us/magazine/hh456402.aspx"&gt;Stephen Toub&amp;#39;s article about async performance&lt;/a&gt; for more information.&lt;/p&gt;  &lt;h3&gt;ForEach&lt;/h3&gt;  &lt;p&gt;I&amp;#39;d like to get ForEach out of the way first, as it&amp;#39;s so simple: it&amp;#39;s literally just iterating over the tasks, awaiting them and propagating the result to the action. We get the &amp;quot;return a task which will wait until we&amp;#39;ve finished&amp;quot; for free by virtue of making it an async method.&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// Executes the given action on each of the tasks in turn, in the order of&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// the sequence. The action is passed the result of each task.&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt; Task ForEach&amp;lt;T&amp;gt;(IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; tasks, Action&amp;lt;T&amp;gt; action)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; task &lt;span class="Statement"&gt;in&lt;/span&gt; tasks)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; T value = &lt;span class="Modifier"&gt;await&lt;/span&gt; task;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; action(value);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Simple, right? Let&amp;#39;s get onto the meat...&lt;/p&gt;  &lt;h5&gt;OrderByCompletion&lt;/h5&gt;  &lt;p&gt;This is the tricky bit, and I&amp;#39;ve actually split it into two methods to make it slightly easier to comprehend. The PropagateResult method feels like it could be useful in other composition methods, too.&lt;/p&gt;  &lt;p&gt;The basic plan is:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Copy the input tasks to a list: we need to work out how many there are &lt;em&gt;and&lt;/em&gt; iterate over them, so let&amp;#39;s make sure we only iterate once &lt;/li&gt;    &lt;li&gt;Create a collection of TaskCompletionSource&amp;lt;T&amp;gt; references, one for each input task. Note that we&amp;#39;re not associating any particular input task with any particular completion source - we just need the same number of them &lt;/li&gt;    &lt;li&gt;Declare an integer to keep track of &amp;quot;the next available completion source&amp;quot; &lt;/li&gt;    &lt;li&gt;Attach a continuation to each input task which will be increment the counter we&amp;#39;ve just declared, and propagate the just-completed task&amp;#39;s status &lt;/li&gt;    &lt;li&gt;Return a view onto the collection of TaskCompletionSource&amp;lt;T&amp;gt; values, projecting each one to its Task property &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Once you&amp;#39;re happy with the idea, the implementation isn&amp;#39;t too surprising (although it &lt;em&gt;is&lt;/em&gt; quite long):&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// Returns a sequence of tasks which will be observed to complete with the same set&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// of results as the given input tasks, but in the order in which the original tasks complete.&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; OrderByCompletion&amp;lt;T&amp;gt;(IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; inputTasks)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Copy the input so we know it&amp;#39;ll be stable, and we don&amp;#39;t evaluate it twice&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; inputTaskList = inputTasks.ToList();     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Could use Enumerable.Range here, if we wanted...&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; completionSourceList = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;TaskCompletionSource&amp;lt;T&amp;gt;&amp;gt;(inputTaskList.Count);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i = 0; i &amp;lt; inputTaskList.Count; i++)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; completionSourceList.Add(&lt;span class="Keyword"&gt;new&lt;/span&gt; TaskCompletionSource&amp;lt;T&amp;gt;());     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// At any one time, this is &amp;quot;the index of the box we&amp;#39;ve just filled&amp;quot;.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// It would be nice to make it nextIndex and start with 0, but Interlocked.Increment&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// returns the incremented value...&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; prevIndex = -1;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// We don&amp;#39;t have to create this outside the loop, but it makes it clearer&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// that the continuation is the same for all tasks.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Action&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; continuation = completedTask =&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; index = Interlocked.Increment(&lt;span class="MethodParameter"&gt;ref&lt;/span&gt; prevIndex);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; source = completionSourceList[index];     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; PropagateResult(completedTask, source);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; };     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; inputTask &lt;span class="Statement"&gt;in&lt;/span&gt; inputTaskList)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// TODO: Work out whether TaskScheduler.Default is really the right one to use.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; inputTask.ContinueWith(continuation,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; CancellationToken.None,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TaskContinuationOptions.ExecuteSynchronously,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TaskScheduler.Default);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; completionSourceList.Select(source =&amp;gt; source.Task);     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// Propagates the status of the given task (which must be completed) to a task completion source&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// (which should not be).&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; PropagateResult&amp;lt;T&amp;gt;(Task&amp;lt;T&amp;gt; completedTask,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; TaskCompletionSource&amp;lt;T&amp;gt; completionSource)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;switch&lt;/span&gt; (completedTask.Status)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;case&lt;/span&gt; TaskStatus.Canceled:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; completionSource.TrySetCanceled();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;case&lt;/span&gt; TaskStatus.Faulted:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; completionSource.TrySetException(completedTask.Exception.InnerExceptions);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;case&lt;/span&gt; TaskStatus.RanToCompletion:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; completionSource.TrySetResult(completedTask.Result);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;default&lt;/span&gt;:     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// TODO: Work out whether this is really appropriate. Could set&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// an exception in the completion source, of course...&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="String"&gt;&amp;quot;Task was not completed&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;You&amp;#39;ll notice there are a couple of TODO comments there. The exception in PropagateResult really &lt;em&gt;shouldn&amp;#39;t&lt;/em&gt; happen - the continuation shouldn&amp;#39;t be called when the task hasn&amp;#39;t completed. I still need to think carefully about how tasks should propagate exceptions though.&lt;/p&gt;  &lt;p&gt;The arguments to ContinueWith are more tricky: working through my TimeMachine class and some unit tests with Bill Wagner last week showed just how little I know about how SynchronizationContext, the task awaiters, task schedulers, and TaskContinuationOptions.ExecuteSynchronously all interact. I would &lt;em&gt;definitely&lt;/em&gt; need to look into that more deeply before TimeMachine was really ready for heavy use... which means &lt;em&gt;you&lt;/em&gt; should probably be looking at the TPL in more depth too.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;Sure enough, when you run the code, the results appear in order, as the tasks complete. Here&amp;#39;s one sample of the output:&lt;/p&gt;  &lt;div class="code"&gt;Initial order: 335 468 1842 1991 2512 2603 270 2854 1972 1327   &lt;br /&gt;In order of completion:    &lt;br /&gt;270    &lt;br /&gt;335    &lt;br /&gt;468    &lt;br /&gt;1327    &lt;br /&gt;1842    &lt;br /&gt;1972    &lt;br /&gt;1991    &lt;br /&gt;2512    &lt;br /&gt;2603    &lt;br /&gt;2854 &lt;/div&gt;  &lt;p&gt;TODOs aside, the code in this post is remarkable (which I can say with modesty, as I&amp;#39;ve only refactored it from the code sent to me by another reader and Stephen Toub). It makes me smile every time I &lt;em&gt;think&lt;/em&gt; about the seemingly-impossible job it accomplishes. I suspect this approach could be useful in any number of composition blocks - it&amp;#39;s definitely one to remember.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1804970" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/t0SgYtV4iDA" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+5/default.aspx">C# 5</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/async/default.aspx">async</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx">Eduasync</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/01/16/eduasync-part-19-ordering-by-completion-ahead-of-time.aspx</feedburner:origLink></item><item><title>Coding in the style of Glee</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/8MoNrulucZg/coding-in-the-style-of-glee.aspx</link><pubDate>Sun, 15 Jan 2012 20:07:55 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1804883</guid><dc:creator>skeet</dc:creator><slash:comments>0</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1804883</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1804883</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/01/15/coding-in-the-style-of-glee.aspx#comments</comments><description>&lt;p&gt;As &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2012/01/15/codemash-2012-report.aspx"&gt;previously mentioned&lt;/a&gt;, at CodeMash 2012 I gave a very silly Pecha Kucha talk entitled &amp;quot;Coding in the style of Glee&amp;quot;. The video is &lt;a href="http://youtu.be/xDTJ6iVgMWs?hd=1"&gt;on YouTube&lt;/a&gt;, or can be seen embedded below:&lt;/p&gt; &lt;iframe height="315" src="http://www.youtube.com/embed/xDTJ6iVgMWs" frameborder="0" width="560"&gt;&lt;/iframe&gt;  &lt;p&gt;(There&amp;#39;s also &lt;a href="http://youtu.be/11u_DwaT3Zw?hd=1"&gt;another YouTube video&lt;/a&gt; from a different angle.)&lt;/p&gt;  &lt;p&gt;This post gives the 20 slides (which were just text; no fancy pictures unlike my competitors) and what I &lt;em&gt;meant&lt;/em&gt; to say about them. (Edited very slightly to remove a couple of CodeMash-specific in-jokes.) Don&amp;#39;t forget that each slide was only up for 20 seconds.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Coding in the style of Glee&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As you may know, I’m from the UK, and it’s wonderful to be here. This is my first US conference, so it’s great to be in the country which has shared with the world its most marvellous cultural output: the Fox show, Glee.&lt;/p&gt;  &lt;p&gt;At first I watched it just for surface story – but now I know better – I know that really, the songs are all about the culture and practice of coding.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;(It isn&amp;#39;t easy) Bein&amp;#39; Green&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;When I started coding, it was on a ZX Spectrum, in Basic. It was hard, but the computer came with a great manual. I later learned C from a ringbinder of some course or other – and entirely failed to understand half the language. Of course, this was before Stack Overflow, when it was really hard being a newbie – where could you turn for information?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Getting to know you&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Over time I became semi-competent in C, with the help of friends. But learning is a constant process, of course – getting to know new languages and platforms is just part of a good dev&amp;#39;s life every day.&lt;/p&gt;  &lt;p&gt;Learning itself is a skill – how similar it is to getting to know small children, I leave to your imagination.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Man in the Mirror&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Glee doesn’t just talk about the coding experience, of course – it talks about specific technologies. This Michael Jackson song is talking about reflection, of course. Although the idea wasn’t new in Java, it was new to me – and now it would be almost unthinkable to come up with a new platform which didn’t let you find out about what was in the code.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bridge over Troubled Water&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Another technology covered beautifully by Glee is the interop. We’re in a big world, and we always need to talk to other systems. Whether it’s over JNI (heaven help you), P/Invoke, SOAP, REST – whatever, I hope next time you connect to another system, you’ll hear this haunting Simon and Garfunkel melody in the background.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;I will survive&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;And who could forget persistence frameworks. I’m not sure whether Gloria Gaynor had Hibernate and the Entity Framework in mind when she sang this, but I’m utterly convinced that the Glee writers did. When you submit your data, it’s just got to survive – what else would you want?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;You can&amp;#39;t always get what you want&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;We’d all like perfect specifications, reliable libraries, ideal languages, etc – but that’s just not going to happen. It’s possible that of course you won’t get what you need – even if you try real hard. But hey, you might just. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Lean on me (or Agile on me)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;(I didn&amp;#39;t actually have notes written for this one. Copied from the video.)&lt;/p&gt;  &lt;p&gt;Glee sympathizes with you - but it also have a bit of an answer: lean on me. Lean and agile development, so we can adapt to constantly changing specifications, and eventually we will have something that is useful. Maybe nothing like what we initially envisaged, but it will be something useful.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Losing my Religion&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Of course, we don’t always stay in love with a platform. I’d like to dedicate this slight to Enterprise Java. Fortunately I never had to deal with Enterprise Java Beans, but I “enjoyed” enough other J2EE APIs to make me yearn for a world without BeanProcessorFactoryFactories.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Anything Goes&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Now I’m pretty conservative – only in terms of coding, mind you. I’m a statically typed language guy. But Glee celebrates dynamic languages too – languages where really, anything goes until you try to execute it. Even though I haven’t gone down the dynamic route myself much, it’s important that we all welcome the diversity of languages and platforms we have.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Get Happy&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Along with the rise of dynamic languages, we seem to have seen a rise of happy developers. We’ve always had enthusiastic developers, but there’s a certain air about your typical Ruby on Rails developer which feels new to me. Again, I’m not a Ruby fan myself – but it’s always nice to see other happy people, and maybe one day I’ll see the light.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Bust your Windows&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I don’t know what I can say about this song. Do the Glee writers have it in for Microsoft? I don’t remember “Bust your OSX” or “Bust your Linux” for example. Only Windows is targeted here.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Safety Dance&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;One big change for me since joining Google is increased awareness of the need for redundancy – the intricate dance we need to perform to create a service which will stay up no matter what. Where redundancy is a dirty word in most of industry, as developers we celebrate it – and will do anything we can to avoid…&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Only Exception&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;… a single point of failure.&lt;/p&gt;  &lt;p&gt;(Yes, that really is all I&amp;#39;d prepared for that slide. Hence the need for improvisation.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Telephone&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;(From video.) Glee celebrates the rise of phone apps. Who these days could be unaware of the importance of the development of mobile applications? And obviously, we can credit the iPhone for that, but since the iPhone, and just smart phone apps, we&amp;#39;ve also started...&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;U Can&amp;#39;t Touch This&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;(From video.) Tablets! And touch screen devices of all kinds. So Windows 8 - very touch-based, and sooner or later we&amp;#39;re all going to have to get with it. I don&amp;#39;t do UIs, I&amp;#39;ve never done a touch UI in my life, I have no idea how it works. But clearly it&amp;#39;s one of the ways forward.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Forget You&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;As smart phones and tablets become more ubiquitous and more bound to us as people, privacy has become more important. Glee gave us a timely reminder of the reverse of the persistence early on: we need to be able to forget about users, as well as remember them.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;(A)waiting for a girl like you&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;(From video.) I&amp;#39;d like to leave on an up-note, so: I&amp;#39;m clearly very, very excited (really, really excited) about C# 5 and its await keyword so I ask you - I beg you - be &lt;em&gt;excited&lt;/em&gt; about development. And always bear in mind your users.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;My life would suck without you&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Users rule our world. Can’t live without them, can’t shoot ‘em.&lt;/p&gt;  &lt;p&gt;Celebrate – we do stuff to make users really happy! This is awesome! We should be thrilled!&lt;/p&gt;  &lt;p&gt;(Even for enterprise apps, we’re doing useful stuff. Honest.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Don&amp;#39;t stop believing&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;(From video.) So to sum up: have fun, keep learning, really, really enjoy what you&amp;#39;re doing, and... don&amp;#39;t stop!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1804883" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/8MoNrulucZg" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Wacky+Ideas/default.aspx">Wacky Ideas</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/01/15/coding-in-the-style-of-glee.aspx</feedburner:origLink></item><item><title>CodeMash 2012 report</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/U1lOnDVXmy4/codemash-2012-report.aspx</link><pubDate>Sun, 15 Jan 2012 19:38:42 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1804880</guid><dc:creator>skeet</dc:creator><slash:comments>7</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1804880</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1804880</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/01/15/codemash-2012-report.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m nearly home - on a bus back from Heathrow airport to Reading - returning from &lt;a href="http://codemash.org/"&gt;CodeMash 2012&lt;/a&gt;. This was my first US conference, and I had a &lt;em&gt;wonderful&lt;/em&gt; time. It was pretty densely packed in terms of presenting / recording for me:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I presented two back-to-back sessions jointly with Bill Wagner, on async. These went down really well (particularly Bill&amp;#39;s genius idea of using the Doctor Who quote about time being a &amp;quot;big ball of wibbly-wobbly, timey-wimey stuff&amp;quot;) and were &lt;em&gt;great&lt;/em&gt; fun to give. Bill&amp;#39;s a class act, and I think we got the balance between use and underpinnings about right. &lt;/li&gt;    &lt;li&gt;I recorded a &lt;a href="http://hanselminutes.com/"&gt;podcast with Scott Hanselman&lt;/a&gt; (we were going to record two, but the first one ended up being longer than expected) &lt;/li&gt;    &lt;li&gt;I presented a talk on &amp;quot;C#&amp;#39;s Greatest Mistakes&amp;quot; which ended up being somewhere between a discussion on language design, and a demonstration of surprising &amp;quot;features&amp;quot; of C#. It overran by 15 minutes without me coming &lt;em&gt;close&lt;/em&gt; to running out of things to say, but hopefully it was useful. It was a somewhat rambly session, but at least I warned folks of that up-front. It would be nice to be able to present the same sort of material in a really &amp;quot;tight&amp;quot; way, but I&amp;#39;m just not sure how to. &lt;/li&gt;    &lt;li&gt;I gave a 20x20 &amp;quot;Pecha Kucha&amp;quot; talk called &amp;quot;Coding in the style of Glee&amp;quot; as the silliest topic I could come up with on short notice. This was absolutely terrifying and extremely silly. I only came third in the contest (and the winner, Leon, was simply &lt;em&gt;phenomenal&lt;/em&gt;) but I was happy that I&amp;#39;d only embarrassed myself about as much as I&amp;#39;d expected to. The &lt;a href="http://youtu.be/xDTJ6iVgMWs?hd=1"&gt;YouTube video&lt;/a&gt; of this is already up, and I&amp;#39;ll write a blog post with the slide titles and what I was &lt;em&gt;trying&lt;/em&gt; to say in them :)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Unfortunately due to last minute async prep and desperately trying to cobble together slides for the Glee talk, I didn&amp;#39;t have time to actually attend as many talks as I&amp;#39;d have liked. Even though I was &lt;em&gt;present&lt;/em&gt; for the whole of the Scala Koans session in the PreCompilr on Wednesday, I found myself next to &lt;a href="http://mindviewinc.com/Index.php"&gt;Bruce Eckel&lt;/a&gt;, and ended up chatting with him for most of the time. It would have been a bit of a waste not to, really. (And at least &lt;em&gt;some&lt;/em&gt; of that talking was Scala-related...) I also watched the whole of the &lt;a href="http://www.bradygaster.com/codemash-signalr-talk"&gt;SignalR presentation by Brady Gaster&lt;/a&gt; - where I was apparently the only person in the room with an aversion to &amp;quot;dynamic&amp;quot; in C# 4. That made me the butt of a &lt;em&gt;few&lt;/em&gt; jokes, but not too many for comfort.&lt;/p&gt;  &lt;p&gt;In terms of C#-related talks, I went to the first half of Dustin Campbell&amp;#39;s Roslyn session, but was somewhat distracted by putting together Glee slides and had to leave half way through to hand them in. My final session of the conference was Bill Wagner&amp;#39;s &amp;quot;Stunt coding in C# - I dare you to try this at home&amp;quot; which was excellent, and a very fitting end to the conference for me.&lt;/p&gt;  &lt;p&gt;Highlights of the conference for me:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Messing with Bill Wagner&amp;#39;s code at the end of not just our joint async talk but also his Stunt Coding talk. I&amp;#39;ve never before asked a presented whether they mind me just stealing the keyboard, but I was confident that Bill (and the attendees) would get a kick out of it - and the code &lt;em&gt;was&lt;/em&gt; nicer afterwards :) &lt;/li&gt;    &lt;li&gt;Meeting &lt;em&gt;so&lt;/em&gt; many people... some that I&amp;#39;ve met before (I hadn&amp;#39;t seen &lt;a href="http://www.tedneward.com/"&gt;Ted Neward&lt;/a&gt; since I gate-crashed a party at his house after the MVP 2005 Summit), some I&amp;#39;d met virtually but not physically before (like Bill) and there loads of other folks I&amp;#39;d never known at all before - including &lt;a href="https://twitter.com/#!/coridrew"&gt;Cori Drew&lt;/a&gt;. Cori simply seemed to pop up &lt;em&gt;everywhere -&lt;/em&gt; I swear she had about 20 clones at CodeMash. (She also recorded the video of the Glee talk, and it&amp;#39;s her laughter you can hear - thanks very much, Cori!) Everyone at the conference was incredibly friendly, and I was really touched by how many people said on the last day that they&amp;#39;d appreciated me making the long trip.&lt;/li&gt;    &lt;li&gt;Confounding &lt;a href="https://twitter.com/#!/dcampbell"&gt;Dustin Campbell&lt;/a&gt; and &lt;a href="https://twitter.com/#!/pilchie"&gt;Kevin Pilch-Bisson&lt;/a&gt; with my &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx"&gt;evil generic overloading puzzle&lt;/a&gt;. Just to be clear, these are two seriously smart guys and this was a friendly over-lunch challenge. It&amp;#39;s always a privilege to meet more of the team responsible for C# and Visual Studio.&lt;/li&gt;    &lt;li&gt;The number of families who came - this is something I&amp;#39;ve never seen at other conferences, and it really made a difference in terms of the atmosphere of the non-dev bits. It was fabulous to see the kids in the water park, for example. Even out of just attendees, there was a greater proportion of women at CodeMash than at other conferences I&amp;#39;ve been to - obviously still vastly outnumbered by the men, but it was nice to see &lt;em&gt;some&lt;/em&gt; improvement on that front. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This will probably be my only international conference for 2012, so it&amp;#39;s a good job that it was so wonderfully organized. I really hope I have the chance to attend next year too. Many thanks to everyone who helped make it such a special conference.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1804880" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/U1lOnDVXmy4" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/01/15/codemash-2012-report.aspx</feedburner:origLink></item><item><title>Eduasync part 18: Changes between the Async CTP and the Visual Studio 11 Preview</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/G48vdcVNoSQ/eduasync-part-18-changes-between-the-async-ctp-and-the-visual-studio-11-preview.aspx</link><pubDate>Thu, 12 Jan 2012 01:34:31 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1804610</guid><dc:creator>skeet</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1804610</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1804610</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/01/12/eduasync-part-18-changes-between-the-async-ctp-and-the-visual-studio-11-preview.aspx#comments</comments><description>&lt;p&gt;In preparation for CodeMash, I&amp;#39;ve been writing some more async code and decompiling it with Reflector. This time I&amp;#39;m using the Visual Studio 11 Developer Preview - the version which installs alongside Visual Studio 2010 under Windows 7. (Don&amp;#39;t ask me about any other features of Visual Studio 11 - I haven&amp;#39;t explored it thoroughly; I&amp;#39;ve really only used it for the C# 5 bits.)&lt;/p&gt;  &lt;p&gt;There have been quite a few changes since the CTP - they&amp;#39;re not &lt;em&gt;visible&lt;/em&gt; changes in terms of code that you&amp;#39;d normally write, but the state machine generated by the C# compiler is reasonably different. In this post I&amp;#39;ll describe the differences, as best I understand them. There are still a couple of things I don&amp;#39;t understand (which I&amp;#39;ll highlight within the post) but overall, I think I&amp;#39;ve got a pretty good handle on why the changes have been made.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m going to assume you already have a &lt;em&gt;reasonable&lt;/em&gt; grasp of the basic idea of async and how it works - the way that the compiler generates a state machine to represent an async method or anonymous function, with originally-local variables being promoted to instance variables within the state machine, etc. If the last sentence was a complete mystery to you, see &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/05/20/eduasync-part-7-generated-code-from-a-simple-async-method.aspx"&gt;Eduasync part 7&lt;/a&gt; for more information. I don&amp;#39;t expect you to remember the &lt;em&gt;exact&lt;/em&gt; details of what was in the previous CTP though :)&lt;/p&gt;  &lt;h2&gt;Removal of iterator block leftovers&lt;/h2&gt;  &lt;p&gt;In the CTP, the code for async methods was based on the iterator block implementation. I suspect that&amp;#39;s still the case, but possibly sharing just a little less code. There used to be a few methods and fields which weren&amp;#39;t used in async methods, but now they&amp;#39;re gone:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;There&amp;#39;s no now constructor, so no need for the &amp;quot;skeleton&amp;quot; method which replaces the real async method to pass in 0 as the initial state. &lt;/li&gt;    &lt;li&gt;There&amp;#39;s no Dispose method. &lt;/li&gt;    &lt;li&gt;There&amp;#39;s no disposing field. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It&amp;#39;s nice to see these gone, but it&amp;#39;s not terribly interesting. Now on to the bigger changes...&lt;/p&gt;  &lt;h2&gt;Large structural changes&lt;/h2&gt;  &lt;p&gt;There&amp;#39;s a set of related structural changes which don&amp;#39;t make sense individually. I&amp;#39;ll describe them first, then look at how it all hangs together, and my guess as to the reasoning behind.&lt;/p&gt;  &lt;h3&gt;The state machine is now a struct&lt;/h3&gt;  &lt;p&gt;The declaration of the nested type for the state machine is now something like this:&lt;/p&gt;  &lt;div class="code"&gt;[CompilerGenerated]    &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;struct&lt;/span&gt; StateMachine : IStateMachine     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Fields common to all async state machines&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// (with caveats)&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; state;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; awaiter;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; AsyncTaskMethodBuilder&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; builder;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; Action moveNextDelegate;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; stack;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Hoisted local variables&lt;/span&gt;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Methods&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; [DebuggerHidden]     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; SetMoveNextDelegate(Action action) { ... }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; MoveNext() { ... }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The caveats around the common field are in terms of the return type of the async method (which determines the type of builder used) and whether or not there are any awaits (if there are no awaits, the stack and awaiter fields aren&amp;#39;t generated).&lt;/p&gt;  &lt;p&gt;Note that throughout this blog post I&amp;#39;ve changed the names of fields and types - in reality they&amp;#39;re all &amp;quot;unspeakable&amp;quot; names including angle-brackets, just like all compiler-generated names.&lt;/p&gt;  &lt;h3&gt;There&amp;#39;s a new assembly-wide interface&lt;/h3&gt;  &lt;p&gt;As you can see from the code above, the state machine implements an interface (actually called &amp;lt;&amp;gt;t__IStateMachine). One of these is created in the global namespace in each assembly that contains at least one async method or anonymous function, and it looks like this:&lt;/p&gt;  &lt;div class="code"&gt;[CompilerGenerated]    &lt;br /&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;interface&lt;/span&gt; IStateMachine     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;void&lt;/span&gt; SetMoveNextDelegate(Action action);     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The implementation for this method is always the same, and it&amp;#39;s trivial:&lt;/p&gt;  &lt;div class="code"&gt;[DebuggerHidden]    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; SetMoveNextDelegate(Action action)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.moveNextDelegate = action;     &lt;br /&gt;} &lt;/div&gt;  &lt;h3&gt;Simplified skeleton method&lt;/h3&gt;  &lt;p&gt;The method which starts the state machine, which I&amp;#39;ve been calling the &amp;quot;skeleton&amp;quot; method everywhere, is now a bit simpler than it was. Something like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; FooAsync()     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; StateMachine machine = &lt;span class="Keyword"&gt;new&lt;/span&gt; StateMachine();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; machine.builder = AsyncVoidMethodBuilder.Create();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; machine.MoveNext();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; machine.builder.Task;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;In fact if you decompile the IL, you&amp;#39;ll see that it &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; explicitly initialize the variable to start with - it just declares it, sets the builder field and then calls MoveNext(). That&amp;#39;s not valid C# (as all the struct&amp;#39;s fields aren&amp;#39;t initialized), but it &lt;em&gt;is&lt;/em&gt; valid IL. It&amp;#39;s &lt;em&gt;equivalent&lt;/em&gt; to the code above though. Note how there&amp;#39;s nothing to set the continuation - where previously the moveNextDelegate field would be populated within the skeleton method.&lt;/p&gt;  &lt;h3&gt;Just-in-time delegate creation&lt;/h3&gt;  &lt;p&gt;Now that the skeleton method doesn&amp;#39;t create the delegate representing the continuation, it can be done when it&amp;#39;s first required - which is when we first encounter an await expression for an awaitable which hasn&amp;#39;t already completed. (If the awaitable has completed before we await it, the generated code skips the continuation and just uses the results immediately and synchronously).&lt;/p&gt;  &lt;p&gt;The code for that delegate creation is slightly trickier than you might expect, however. It looks something like this:&lt;/p&gt;  &lt;div class="code"&gt;Action action = &lt;span class="Keyword"&gt;this&lt;/span&gt;.moveNextDelegate;     &lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt; (action == &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; task = &lt;span class="Keyword"&gt;this&lt;/span&gt;.builder.Task;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; action = &lt;span class="Keyword"&gt;new&lt;/span&gt; Action(&lt;span class="Keyword"&gt;this&lt;/span&gt;.MoveNext);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ((IStateMachine) action.Target).SetMoveNextDelegate(action);     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;There are two oddities here, one of which I mostly understand and one of which I don&amp;#39;t understand at all.&lt;/p&gt;  &lt;p&gt;I really don&amp;#39;t understand the &amp;quot;task&amp;quot; variable here. Why do we need to exercise the AsyncTaskMethodBuilder.Task property? We don&amp;#39;t use the result anywhere... does forcing this flush some memory buffer? I have no clue on this one. &lt;strong&gt;(See the update at the bottom of the post...)&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The part about setting the delegate via the interface makes more sense, but it&amp;#39;s subtle. You might &lt;em&gt;expect&lt;/em&gt; code like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Looks sensible, but is actually slightly broken&lt;/span&gt;     &lt;br /&gt;Action action = &lt;span class="Keyword"&gt;this&lt;/span&gt;.moveNextDelegate;     &lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt; (action == &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; action = &lt;span class="Keyword"&gt;new&lt;/span&gt; Action(&lt;span class="Keyword"&gt;this&lt;/span&gt;.MoveNext);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.moveNextDelegate = action;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;That would &lt;em&gt;sort of&lt;/em&gt; work - but we&amp;#39;d end up needing to recreate the delegate each time we encountered an appropriate await expression. Although the above code saves the value to the field, it saves it within the current value of the state machine... &lt;em&gt;after&lt;/em&gt; we&amp;#39;ve boxed that value as the target of the delegate. The value we want to mutate is the one &lt;em&gt;within the box&lt;/em&gt; - which is precisely why there&amp;#39;s an interface, and why the code casts to it.&lt;/p&gt;  &lt;p&gt;We can&amp;#39;t even just unbox and then set the field afterwards - at least in C# - because the unbox operation is always followed by a copy operation in normal C#. I &lt;em&gt;believe&lt;/em&gt; it would be possible for the C# compiler to generate IL which unboxed action.Target &lt;em&gt;without&lt;/em&gt; the copy, and then set the field in that. It&amp;#39;s not clear to me why the team went with the interface approach instead... I would &lt;em&gt;expect&lt;/em&gt; that to be slower (as it requires dynamic dispatch) but I could easily be wrong. Of course, it would also make it impossible to decompile the IL to C#, which would make my talks harder, but don&amp;#39;t expect the C# team to bend the compiler implementation for my benefit ;)&lt;/p&gt;  &lt;p&gt;(As an aside to all of this, I&amp;#39;ve gone back and forth on whether the &amp;quot;slightly broken&amp;quot; implementation would recreate the delegate on &lt;em&gt;every&lt;/em&gt; appropriate await, or only two. I &lt;em&gt;think&lt;/em&gt; it would end up being on every occurrence, as even though on the second occurrence we&amp;#39;d be operating within the context of the first boxed instance, the new delegate would have a reference to a &lt;em&gt;new&lt;/em&gt; boxed copy each time. It does my head in a little bit, trying to think about this... more evidence that mutable structs are evil and hard to reason about. It&amp;#39;s not the wrong decision in this case, hidden far from the gaze of normal developers, but it&amp;#39;s a pain to reason about.)&lt;/p&gt;  &lt;h3&gt;Single awaiter variable&lt;/h3&gt;  &lt;p&gt;In the CTP, each await expression generated a separate field within the state machine, and that field was always of the exact awaiter type. In the VS11 Developer Preview, there&amp;#39;s always exactly &lt;em&gt;one&lt;/em&gt; awaiter field (assuming there&amp;#39;s at least one await expression) and it&amp;#39;s always of type object. It&amp;#39;s used like this:&lt;/p&gt;  &lt;div class="code"&gt;&amp;#160; &lt;span class="InlineComment"&gt;// Single local variable used by both continuation and first-time paths&lt;/span&gt;     &lt;br /&gt;&amp;#160; TaskAwaiter&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; localAwaiter;     &lt;br /&gt;    &lt;br /&gt;&amp;#160; ...     &lt;br /&gt;    &lt;br /&gt;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (conditions-&lt;span class="Statement"&gt;for&lt;/span&gt;-first-time-execution)     &lt;br /&gt;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Code before await&lt;/span&gt;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; localAwaiter = task.GetAwaiter();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (localAwaiter.IsCompleted)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;goto&lt;/span&gt; Await1Completed;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.state = 1;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TaskAwaiter&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;[] awaiterArray = { localAwaiter };     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.awaiter = awaiterArray;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Lazy delegate creation goes here&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; awaiterArray[0].OnCompleted(action);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;;     &lt;br /&gt;&amp;#160; }     &lt;br /&gt;&amp;#160; &lt;span class="InlineComment"&gt;// Continuation would get into here&lt;/span&gt;     &lt;br /&gt;&amp;#160; localAwaiter = ((TaskAwaiter&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;[]) &lt;span class="Keyword"&gt;this&lt;/span&gt;.awaiter)[0];     &lt;br /&gt;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.awaiter = &lt;span class="Keyword"&gt;null&lt;/span&gt;;     &lt;br /&gt;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.state = 0;     &lt;br /&gt;Await1Completed:     &lt;br /&gt;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; result = localAwaiter.GetResult();&amp;#160; &lt;br /&gt;&amp;#160; localA&lt;span class="ValueType"&gt;&lt;font color="#333333"&gt;waiter = &lt;/font&gt;&lt;span class="Modifier"&gt;default&lt;/span&gt;&lt;font color="#333333"&gt;(TaskAwaiter&amp;lt;&lt;/font&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&lt;font color="#333333"&gt;&amp;gt;);&lt;/font&gt;&lt;/span&gt; &lt;/div&gt;  &lt;p&gt;I realize there&amp;#39;s a lot of code here, but it does make some sense:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The value of the awaiter field is always either null, or a reference to a single-element array of the awaiter type for one of the await expressions. &lt;/li&gt;    &lt;li&gt;A single localAwaiter variable is shared between the two code paths, populated either from the awaitable (on the initial code path) or by copying the value from the array (in the second code path). &lt;/li&gt;    &lt;li&gt;The field is always set to null and the local variable is set to its default value after use, presumably for the sake of garbage collection &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;It&amp;#39;s basically a nice way of using the fact that we&amp;#39;ll only ever need one awaiter at a time. It&amp;#39;s not clear to me why an array is used instead of either using a reference to the awaiter for class-based awaiters, or simply by boxing for struct-based awaiters. The latter would need the same &amp;quot;unbox without copy&amp;quot; approach discussed in the previous section - so if there&amp;#39;s some reason why that&amp;#39;s actually infeasible, it would explain the use of an array here. We &lt;em&gt;can&amp;#39;t&lt;/em&gt; use the interface trick in this case, as the compiler isn&amp;#39;t in control of the awaiter type (so can&amp;#39;t make it implement an interface).&lt;/p&gt;  &lt;h3&gt;Expression stack preservation&lt;/h3&gt;  &lt;p&gt;This one is actually a fix to a bug in the async CTP, which I&amp;#39;ve &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/06/10/eduasync-part-10-ctp-bug-don-t-combine-multiple-awaits-in-one-statement.aspx"&gt;written about before&lt;/a&gt;. We&amp;#39;re used to the stack containing our local variables (in the absence of iterator blocks, captured variables etc, and modulo the stack being an implementation detail) but it&amp;#39;s also used for intermediate results within a single statement. For example, consider this block of code:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; x = 10;     &lt;br /&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; y = 5;     &lt;br /&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; z = x + 50 * y; &lt;/div&gt;  &lt;p&gt;That last line is effectively:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Load the value of x onto the stack &lt;/li&gt;    &lt;li&gt;Load the value 50 onto the stack &lt;/li&gt;    &lt;li&gt;Load the value of y onto the stack &lt;/li&gt;    &lt;li&gt;Multiply the top two stack values (50 and y) leaving the result on the stack &lt;/li&gt;    &lt;li&gt;Add the top two stack values (x and the previously-computed result) leaving the result on the stack &lt;/li&gt;    &lt;li&gt;Store the top stack value into z &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now suppose we want to turn y into a Task&amp;lt;int&amp;gt;:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; x = 10;     &lt;br /&gt;Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; y = Task.FromResult(5);     &lt;br /&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; z = x + 50 * &lt;span class="Modifier"&gt;await&lt;/span&gt; y; &lt;/div&gt;  &lt;p&gt;Our state machine needs to make sure that it will preserve the same behaviour as the synchronous version, so it needs the same sort of stack. In the new-style state machine, all of that stack is saved in the &amp;quot;stack&amp;quot; field. It&amp;#39;s only one field, but may need to represent multiple different types within the code at various different await expressions - in the code above, for example, it represents two int values. As far as I can discover, the C# compiler generates code which uses the actual type of the value it needs, if it only requires a single value. If it needs multiple values, it uses an appropriate Tuple type, nesting tuples if it goes beyond the number of type parameters supported by the Tuple&amp;lt;...&amp;gt; family of types. So in our case above, we end up with code a &lt;em&gt;bit&lt;/em&gt; like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Local variable used in both paths&lt;/span&gt;     &lt;br /&gt;Tuple&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; tuple;     &lt;br /&gt;    &lt;br /&gt;...     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Code before the await&lt;/span&gt;     &lt;br /&gt;&lt;span class="Statement"&gt;if&lt;/span&gt; (conditions-&lt;span class="Statement"&gt;for&lt;/span&gt;-first-time-execution)&amp;#160; &lt;br /&gt;{&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; tuple = &lt;span class="Keyword"&gt;new&lt;/span&gt; Tuple&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;(&lt;span class="Keyword"&gt;this&lt;/span&gt;.x, 50);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.stack = tuple;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; ...     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Continuation would get into here&lt;/span&gt;     &lt;br /&gt;tuple = (Tuple&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, &lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;) &lt;span class="Keyword"&gt;this&lt;/span&gt;.stack;     &lt;br /&gt;&lt;span class="InlineComment"&gt;// IL copies the values from the tuple onto the stack at this point&lt;/span&gt;     &lt;br /&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;.stack = &lt;span class="Keyword"&gt;null&lt;/span&gt;;     &lt;br /&gt;    &lt;br /&gt;...     &lt;br /&gt;    &lt;br /&gt;&lt;span class="InlineComment"&gt;// Both the fast and slow code paths get here eventually&lt;/span&gt;     &lt;br /&gt;&lt;span class="Keyword"&gt;this&lt;/span&gt;.z = stack0 + stack1 * awaiter.GetResult() &lt;/div&gt;  &lt;p&gt;I say it&amp;#39;s a &lt;em&gt;bit&lt;/em&gt; like this, because it&amp;#39;s hard to represent the IL exactly in C# in this case. The tuple is only created if it&amp;#39;s needed, i.e. not in the already-completed fast path. In that case, the values are loaded onto the stack but &lt;em&gt;not&lt;/em&gt; then put into the tuple - execution skips straight to the code which uses the values already on the stack.&lt;/p&gt;  &lt;p&gt;When the awaitable &lt;em&gt;isn&amp;#39;t&lt;/em&gt; complete immediately, then a Tuple&amp;lt;int, int&amp;gt; is created, stored in the &amp;quot;stack&amp;quot; field, and the continuation is handed to the awaiter. On continuation, the tuple is loaded back from the &amp;quot;stack&amp;quot; field (and cast accordingly), the values are loaded onto the stack - and then we&amp;#39;re back into the common code path of fetching the value and performing the add and multiply operations.&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;As far as I&amp;#39;m aware, those are the most noticeable changes in the generated code. There may well still be a load more changes in Task&amp;lt;T&amp;gt; and the TPL in general - I wouldn&amp;#39;t be at all surprised - but that&amp;#39;s harder to investigate.&lt;/p&gt;  &lt;p&gt;I&amp;#39;m sure all of this has been done in the name of performance (and correctness, in the case of stack preservation). The state machine is now much smaller in terms of the number of fields it requires, and objects are created locally as far as possible (including the state machine itself only requiring heap allocation if there&amp;#39;s ever a &amp;quot;slow&amp;quot; awaitable). I suspect there&amp;#39;s still some room for optimization, however:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Both the awaiter and the delegate use careful boxing and either arrays or a mutating interface to allow the boxed value to be changed. I suspect that using unbox with the concrete type, but without copying the value, would be more efficient. I may attempt to work this theory up into a test at some point. &lt;/li&gt;    &lt;li&gt;If there&amp;#39;s only one awaiter type (usually TaskAwaiter&amp;lt;T&amp;gt; for some T), that type could be used instead of object, potentially reducing heap optimization &lt;/li&gt;    &lt;li&gt;I&amp;#39;ve no idea why the builder.Task property is explicitly fetched and then the results discarded&lt;/li&gt;    &lt;li&gt;If there&amp;#39;s only one await expression, the &amp;quot;stack&amp;quot; field can be strongly typed, which would also avoid boxing if only a single value needs to be within that stack &lt;/li&gt;    &lt;li&gt;The stack field could be removed entirely when it&amp;#39;s not needed for intermediate stack value preservation. (I believe that would be the case reasonably often.) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The use of mutable value types is really fascinating (for me, at least) - I&amp;#39;m sure most people on the C# team would still say they&amp;#39;re evil, but when they&amp;#39;re used in a carefully controlled environment where real developers don&amp;#39;t have to reason about their behaviour, they can be useful.&lt;/p&gt;  &lt;p&gt;Next time, I&amp;#39;ll hopefully get back to the idea I promised to write up before, about ordering a collection of tasks in completion order... before they&amp;#39;ve completed. (Well, sort of.) Should be fun...&lt;/p&gt;  &lt;h2&gt;Update (January 16th 2012)&lt;/h2&gt;  &lt;p&gt;Stephen Toub got in touch with me after I posted the original version of this blog entry, to explain the use of the Task property. Apparently the idea is that at this point, we &lt;em&gt;know&lt;/em&gt; we&amp;#39;re going to return out of the state machine, so the skeleton method is going to access the Task property anyway. However, as we haven&amp;#39;t scheduled the continuation yet we &lt;em&gt;also&lt;/em&gt; know that nothing will be accessing the Task property on a different thread. If we access it now for the first time, we can lazily allocate the task &lt;em&gt;in the same thread that created the AsyncMethodBuilder, with no risk of contention.&lt;/em&gt; If we can force there to be a task ready and waiting for whatever accesses it later, we don&amp;#39;t need any synchronization in that area.&lt;/p&gt;  &lt;p&gt;So why might we want to allocate the task lazily in the first place? Well, don&amp;#39;t forget that we might &lt;em&gt;never&lt;/em&gt; have to wait for an await (as it were). We might just have an async method which takes the fast path everywhere. If that&amp;#39;s the case, then for certain cases (e.g. a non-generic, successfully completed task, or a Task&amp;lt;bool&amp;gt; which again has completed successfully) we can reuse the same instance repeatedly. Apparently this laziness isn&amp;#39;t yet part of the VS11 Developer Preview, but the reason for the property access is in preparation for this.&lt;/p&gt;  &lt;p&gt;Another case of micro-optimization - which is fair enough when it&amp;#39;s at a system level :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1804610" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/G48vdcVNoSQ" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+5/default.aspx">C# 5</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/async/default.aspx">async</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx">Eduasync</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/01/12/eduasync-part-18-changes-between-the-async-ctp-and-the-visual-studio-11-preview.aspx</feedburner:origLink></item><item><title>Awaiting CodeMash 2012</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/7y3aScdTwxA/awaiting-codemash-2012.aspx</link><pubDate>Sun, 01 Jan 2012 20:43:10 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1804280</guid><dc:creator>skeet</dc:creator><slash:comments>2</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1804280</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1804280</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2012/01/01/awaiting-codemash-2012.aspx#comments</comments><description>&lt;p&gt;Happy New Year, everyone!&lt;/p&gt;  &lt;p&gt;I&amp;#39;m attempting to make 2012 a quiet year in terms of my speaking engagements - I&amp;#39;ve turned down a few kind offers already, and I expect to do so again during the year. I may well still give user group talks in evenings if I can do so without having to take holiday, but full conferences are likely to be out, especially international ones. This is partly so I can take more time off to support my wife, Holly, who has &lt;a href="http://www.amazon.co.uk/s/ref=sr_tc_2_0?rh=i%3Astripbooks%2Ck%3AHolly+Webb&amp;amp;field-contributor_id=B0034Q363U"&gt;her own books to promote&lt;/a&gt;. This year will be particularly important for Holly as she&amp;#39;s one of the &lt;a href="http://www.worldbookday.com/"&gt;World Book Day 2012&lt;/a&gt; authors - I&amp;#39;m &lt;em&gt;tremendously&lt;/em&gt; proud of her, as you can no doubt imagine.&lt;/p&gt;  &lt;p&gt;However, there&amp;#39;s one international conference I decided to submit proposals for: &lt;a href="http://codemash.org/"&gt;CodeMash&lt;/a&gt;. I&amp;#39;ve never been to this or any other US conference, but I&amp;#39;ve heard fabulous things about it. I&amp;#39;m particularly excited that I&amp;#39;ll be able to present alongside Bill Wagner, a fellow C# author (probably most famous for &lt;a href="http://www.amazon.com/dp/0321245660"&gt;Effective C#&lt;/a&gt; which I&amp;#39;ve &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2010/09/25/book-review-effective-c-2nd-edition-by-bill-wagner.aspx"&gt;reviewed before now&lt;/a&gt;). Bill and I have never met, although we&amp;#39;ve participated jointly on a &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=611"&gt;.NET Rocks show&lt;/a&gt; before now. I could barely hear Bill when we recorded that though, so it hardly counts :)&lt;/p&gt;  &lt;p&gt;The conference schedule for CodeMash shows Bill and I each giving two talks: two individual ones on general C# (&lt;a href="http://codemash.org/Sessions#C%23+Stunt+Coding%3a+I+Dare+You+to+Try+This+at+Home"&gt;C# Stunt Coding&lt;/a&gt; by Bill, and &lt;a href="http://codemash.org/Sessions#C%23&amp;#39;s+Greatest+Mistakes"&gt;C#&amp;#39;s Greatest Mistakes&lt;/a&gt; by me) and two sessions on the async support in C# 5... async &amp;quot;from the inside&amp;quot; and &amp;quot;from the outside&amp;quot;. Although these have hitherto been shown as separate sessions, everyone involved thought it would make more sense to weave the two together... so this will be a double-length session. Bill will be presenting the &amp;quot;outside&amp;quot; view - how to &lt;em&gt;use&lt;/em&gt; async, basically; I&amp;#39;ll be presenting the &amp;quot;inside&amp;quot; view - how it all hangs together behind the scenes.&lt;/p&gt;  &lt;p&gt;With any luck, this will be much more helpful to the conference attendees, as they should be able to build up confidence in the solid foundations underpinning it all at the same time as seeing how fabulously useful it&amp;#39;ll be for developers. It also means that Bill and I can bounce ideas off each other spontaneously as we go - I intend to pay close attention and learn a thing or two myself!&lt;/p&gt;  &lt;p&gt;It&amp;#39;s pretty much impossible to predict how it&amp;#39;ll all hang together, but I&amp;#39;m really excited about the whole shebang. I&amp;#39;ll be fascinated to see if and how US conferences differ from the various ones this side of the pond... but it does make the whole thing that bit more nerve-wracking. If you&amp;#39;re coming to CodeMash, please grab me and say hi - it never hurts to see a friendly face...&lt;/p&gt;  &lt;p&gt;(Note: Bill has a &lt;a href="http://billwagner.cloudapp.net/Home/Item/LookingforwardtoCodeMashInsideandOutside"&gt;similar blog post&lt;/a&gt; posted just before this one.)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1804280" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/7y3aScdTwxA" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2012/01/01/awaiting-codemash-2012.aspx</feedburner:origLink></item><item><title>Book Review: Fluent C# (Rebecca Riordan, Sams)</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/wg2DJGKWqNY/book-review-fluent-c-rebecca-riordan-sams.aspx</link><pubDate>Mon, 05 Dec 2011 19:26:25 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1803256</guid><dc:creator>skeet</dc:creator><slash:comments>30</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1803256</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1803256</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/12/05/book-review-fluent-c-rebecca-riordan-sams.aspx#comments</comments><description>&lt;p&gt;(As usual, I will be sending the publisher a copy of this review to give them and the author a chance to reply to it before I publish it to the blog. Other than including their comments and correcting any factual mistakes they may point out, I don&amp;#39;t intend to change the review itself.)&lt;/p&gt;  &lt;h3&gt;Resources:&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.informit.com/store/product.aspx?isbn=0672331047"&gt;Publisher page (includes source code download)&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/dp/0672331047"&gt;Amazon&lt;/a&gt; / &lt;a href="http://www.barnesandnoble.com/w/fluent-c-rebecca-m-riordan/1100388197?ean=9780672331046&amp;amp;itm=1&amp;amp;usri=fluent+c%23"&gt;Barnes and Noble&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="https://docs.google.com/document/d/1GNZ77fBu15gPnpmelcujlJVdc_iEvJWjLMd0m2VgStA/edit?hl=en_GB"&gt;My unofficial errata and notes&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://kellyschronicles.wordpress.com/category/fluent/"&gt;A more positive series of review blog posts&lt;/a&gt; (just for balance) &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Introduction and disclaimers&lt;/h3&gt;  &lt;p&gt;In late October, Sams (the publisher) approached me to ask if I&amp;#39;d be interested in reviewing their newest introductory book on C#. Despite my burgeoning review stack, I said I was interested - I&amp;#39;m always on the lookout for good books to recommend. So, the first disclaimer is that this was a review copy - I didn&amp;#39;t have to pay for it. I don&amp;#39;t believe that has biased this review though.&lt;/p&gt;  &lt;p&gt;Second disclaimer: obviously as C# in Depth is also &amp;quot;a book about C#&amp;quot; you might be wondering whether the two books are competitors. I don&amp;#39;t believe this is the case: Fluent C# explicitly talks about its target audience, which is primarily complete newcomers to programming. C# in Depth pretty much requires you to know at least C# 1, or perhaps be very comfortable with a similar language such as Java. I find it hard to imagine someone for whom both books would be suitable.&lt;/p&gt;  &lt;p&gt;Obviously that puts me firmly &lt;em&gt;out&lt;/em&gt; of the target audience. &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/07/08/the-trouble-with-book-reviews.aspx"&gt;As I&amp;#39;ve written before&lt;/a&gt;, if you think the two most important questions to answer in a technical book review are &amp;quot;Is it accurate?&amp;quot; and &amp;quot;How good is at teaching its topic?&amp;quot; then any one person will find it hard to answer both questions. Although I&amp;#39;m far from an expert in some of the areas of the book - notably WPF - I&amp;#39;m sure I don&amp;#39;t have the same approach as a true newcomer. In particular, I find myself asking the questions I&amp;#39;d need the answers to in order to develop software professionally: how do I test it? How does the deployment model work? How does the data flow? These aren&amp;#39;t the same concerns as someone who is coming to programming for the first time. This review should be read with that context in mind: that my approach to the subject matter won&amp;#39;t be the same as a regular reader&amp;#39;s.&lt;/p&gt;  &lt;h3&gt;Physical format and style&lt;/h3&gt;  &lt;p&gt;Fluent C# is &lt;em&gt;very&lt;/em&gt; reminiscent of Head-First C# in its approach, even down to the introductory &amp;quot;why this book is great at teaching you&amp;quot; blurb. It&amp;#39;s all very informal, with lots of pictures, diagrams and reader exercises. It&amp;#39;s a chunky book, at nearly 900 pages including the index - which I&amp;#39;d expect to be pretty daunting to a newcomer. However, that isn&amp;#39;t the main impression you come away with. Instead...&lt;/p&gt;  &lt;p&gt;It&amp;#39;s brown. &lt;strong&gt;Everywhere&lt;/strong&gt;. The diagrams, the text, the pictures - they&amp;#39;re all printed in brown, on off-white paper.&lt;/p&gt;  &lt;p&gt;Combined with using multiple fonts including cursive ones, this makes for a pointlessly irritating reading experience right from the outset, however good or bad the actual content is. Now it&amp;#39;s &lt;em&gt;possible&lt;/em&gt; that this is actually deliberate: I was speaking to someone recently who mentioned some research that shows if you use a hard-to-read font in presentations, people tend to end up reading it several times, so you end up with &lt;em&gt;better&lt;/em&gt; memories of the content than if it had been &amp;quot;clean&amp;quot;. I don&amp;#39;t know if that&amp;#39;s what Sams intended with this book, but I frequently found myself longing for simple black ink on clean white paper.&lt;/p&gt;  &lt;p&gt;Leaving that to one side, I&amp;#39;m not sure I&amp;#39;ll ever &lt;em&gt;really&lt;/em&gt; be a fan of the general tone of books like this, but I can certainly see that it&amp;#39;s popular and therefore presumably helpful to many people. It&amp;#39;s not clear to me whether it&amp;#39;s possible to create a book which retains the valuable elements of this style while casting off the aspects which rub me up the wrong way. It&amp;#39;s something about the enforced jollity which just doesn&amp;#39;t quite sit right, but it wouldn&amp;#39;t surprise me if that were more a peculiarity of my personality than anything about the book. Again, I&amp;#39;ve tried to set this to one side when reviewing the book, but it may come through nonetheless.&lt;/p&gt;  &lt;h3&gt;Structure&lt;/h3&gt;  &lt;p&gt;The book is broken up into the following sections, with several chapters per section:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Getting started (122 pages - finding your way around Visual Studio, debugging, deployment) &lt;/li&gt;    &lt;li&gt;The Language (100 pages - introduction to C#) &lt;/li&gt;    &lt;li&gt;The .NET Framework Library (162 pages - text, date/time APIs, collections - and actually more about C# as a language) &lt;/li&gt;    &lt;li&gt;Best practice (116 pages - inheritance, some principles, design patterns) &lt;/li&gt;    &lt;li&gt;WPF (341 pages) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I&amp;#39;ve included the page count for each section to show just how much is devoted to WPF. The book goes into much more detail about WPF than it does about the C# language itself (for example, drop shadow effects are included, but the &amp;quot;using&amp;quot; statement and nullable value types aren&amp;#39;t). If you want to write any kind of application other than a WPF one, a large part of the book won&amp;#39;t be useful to you. That&amp;#39;s not to say it&amp;#39;s useless per se - and in fact from my point of view, the WPF section was the most useful. The section on brushes is probably the best written in the whole book, for example. At time it &lt;em&gt;feels&lt;/em&gt; to me like the author really wanted to write a book about WPF, but was asked to make it one about C# instead. That may well not be the case at all - it was just an impression.&lt;/p&gt;  &lt;p&gt;Even though the best practice section talks briefly about MVC, MVP and MVVM, it doesn&amp;#39;t really go into enough detail to build anything like a real application - and in fact there&amp;#39;s no coverage of persistence of any form. No files, no XML, no database - nothing below the presentation layer, really. As such, although the book &lt;em&gt;claims&lt;/em&gt; it&amp;#39;s enough to get you started with application development, it actually only provides a veneer. Even though I &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2008/03/21/book-review-head-first-c.aspx"&gt;didn&amp;#39;t like the first edition of Head-First C#&lt;/a&gt; back in 2008, it did at least take the reader end-to-end - the exercises led to complete applications. The best practice section isn&amp;#39;t entirely about architecture and design patterns, however - it&amp;#39;s at this point that inheritance is properly introduced. While I wouldn&amp;#39;t personally count that as a &amp;quot;best practice&amp;quot; as such, it does at least come at the start of the section, before the genuine patterns/architecture areas which would have been harder to understand without that background.&lt;/p&gt;  &lt;p&gt;One aspect which concerned me was the emphasis on the debugger and interactive diagnostics. The author states that developers should expect to spend a large part of their time in the debugger, and she says how she prefers using MessageBox.Show for diagnostics over Console.WriteLine information appearing in the output window. While I&amp;#39;m all for something more sophisticated than Console.WriteLine, there are solutions which are a lot less invasive than popping up a dialog, and which can be left in the code (possibly under an execution-time configuration) to allow diagnostics to be produced for &lt;em&gt;real&lt;/em&gt; systems.&lt;/p&gt;  &lt;p&gt;The &amp;quot;testing and deployment&amp;quot; chapter says nothing about &lt;em&gt;automated&lt;/em&gt; tests - it&amp;#39;s as if the author believes that &amp;quot;testing&amp;quot; only involves &amp;quot;running the app in the debugger and seeing if it breaks&amp;quot;. I hope that&amp;#39;s not actually the case, and I can understand why newcomers ought to at least know about the debugger - but I&amp;#39;d have welcomed at least a few pages &lt;em&gt;introducing&lt;/em&gt; unit testing as a way of recording and checking expectations of how your code behaves. My own preference is to spend as little time in the debugger as possible; I know that&amp;#39;s not always practical, particularly for UI work, but I think it&amp;#39;s a reasonable aim.&lt;/p&gt;  &lt;h3&gt;Accuracy&lt;/h3&gt;  &lt;p&gt;Anyone following me on Twitter or Google+ knows where I&amp;#39;m going with this section. After reading through the book, pen in hand (as I always do, even for the books I like), I decided that it was more important to get out some form of errata quickly than this review. As such, I started a &lt;a href="https://docs.google.com/document/d/1GNZ77fBu15gPnpmelcujlJVdc_iEvJWjLMd0m2VgStA/edit?hl=en_GB"&gt;Google document&lt;/a&gt; which is publicly available to read and add comments to. The result is over 60 pages of notes and errata, and that&amp;#39;s excluding the introduction and table of contents. To be fair to the book, some of those notes are matters of disagreement which are more personal opinion than incontrovertible fact - but there are plenty of simple matters of inaccuracy. Some of the worst are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Claims that String is a value type. (It&amp;#39;s a reference type.) &lt;/li&gt;    &lt;li&gt;Inconsistency between whether arrays are value types or reference types - but consistently claiming that arrays are immutable, with the exception of the size which can be changed (slowly) using Array.Resize. (Array types are always reference types, and they&amp;#39;re always mutable &lt;em&gt;except&lt;/em&gt; the size, which is fixed after creation. Array.Resize creates a &lt;em&gt;new&lt;/em&gt; array, it doesn&amp;#39;t change the size of the existing one.) &lt;/li&gt;    &lt;li&gt;Incorrect syntax for chaining from one constructor to another. &lt;/li&gt;    &lt;li&gt;The claim that &lt;em&gt;all&lt;/em&gt; reference types are mutable. (Some aren&amp;#39;t, and indeed I often aim for immutability. The canonical example of an immutable reference type is String.) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are plenty more - including huge number of samples which simply won&amp;#39;t compile. Whole double page spreads where every class declaration is missing the &amp;quot;class&amp;quot; keyword. Pieces of code using VB syntax... the list goes on. (The VB syntax errors are probably explained by the author&amp;#39;s other book published at the same time: &amp;quot;Fluent Visual Basic&amp;quot;. I suspect there was a certain amount of copy/paste, and the editing process didn&amp;#39;t catch all the changes which were needed to reflect the differences between the languages.)&lt;/p&gt;  &lt;p&gt;Beyond the factually incorrect statements, there&amp;#39;s the matter of terminology. Now I&amp;#39;m well aware that I care more about terminology than more people - but there&amp;#39;s simply no reason to start making up terminology or misusing the perfectly good terminology from the specification. The book has a whole section on &amp;quot;commands&amp;quot; in C#, including things like for statements, switch statements, try/catch/finally statements. Additionally, it mislabels class and namespace declarations as &amp;quot;statements&amp;quot;, and even mislabels using directives as statements - although it later goes back on the latter point. The word &amp;quot;object&amp;quot; is used at various times to mean any of variable, type, class and object, with no sense of consistency that I could fathom. For example, at one point it&amp;#39;s used in two different senses within the same sentence: &amp;quot;As we&amp;#39;ll see, you can define several different kinds of objects (called TYPES) in C#, but the one you&amp;#39;ll probably work with most often is the OBJECT.&amp;quot;&lt;/p&gt;  &lt;p&gt;Both accuracy and staying consistent with accepted terminology (primarily the specification) are &lt;em&gt;particularly&lt;/em&gt; important for newcomers. If there&amp;#39;s a typo in a relatively advanced book - or in one which is about a particular technology (e.g. MVC) rather than an introductory text on a language, the reader is fairly likely to be able to guess what should really be there based on their existing experience. If a beginner comes across the same problem, they&amp;#39;re likely to assume it&amp;#39;s &lt;em&gt;their&lt;/em&gt; fault that the code won&amp;#39;t compile. Likewise if they learn the wrong terminology to start with, they&amp;#39;ll be severely hampered in communicating effectively with other developers - as well as when reading other books.&lt;/p&gt;  &lt;p&gt;I don&amp;#39;t want to make it sound like I expect perfection in a book - just yesterday someone mailed me a correction to C# in Depth, and I&amp;#39;d be foolish to try to hold other authors to standards I couldn&amp;#39;t meet myself. Nor am I suggesting it&amp;#39;s &lt;em&gt;easy&lt;/em&gt; to be both accessible and accurate - so often an author may have an accurate picture of a complex topic, but have to simplify it in their writing, particularly for an introductory book like Fluent C#. But there are limits - and in my view this book goes well past the level of error that I&amp;#39;m willing to put up with.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;I really don&amp;#39;t &lt;em&gt;like&lt;/em&gt; ranting. I don&amp;#39;t &lt;em&gt;like&lt;/em&gt; sounding mean - and I &lt;em&gt;wanted&lt;/em&gt; to like this book. While I like &lt;a href="http://www.amazon.com/dp/0596800959"&gt;C# 4.0 in a Nutshell&lt;/a&gt; and &lt;a href="http://www.amazon.com/dp/0321694694"&gt;Essential C# 4.0&lt;/a&gt;, I&amp;#39;m still looking for a book which I can recommend to readers who want a more &amp;quot;lively&amp;quot; kind of book. Unfortunately I really can&amp;#39;t recommend Fluent C# to anyone - it is simply too inaccurate, and I believe it will cause confusion and instil bad habits in its readers.&lt;/p&gt;  &lt;p&gt;So, what next? I&amp;#39;m &lt;em&gt;hoping&lt;/em&gt; that the publisher and author will take my errata on board for the next printing, and revise it thoroughly. At that point I still don&amp;#39;t think I&amp;#39;d actually &lt;em&gt;like&lt;/em&gt; the book due to its structure and WPF focus (and the colour scheme, which I don&amp;#39;t expect to change), but it would at least be more a matter of taste then.&lt;/p&gt;  &lt;p&gt;I have some reason to be hopeful - because my review of Head-First C# was somewhat like this one, and one of the authors of that book (Andrew Stellman) was &lt;em&gt;incredibly&lt;/em&gt; good about the whole thing, and as a result the &lt;a href="http://www.amazon.com/dp/1449380344"&gt;second edition of Head-First C#&lt;/a&gt; is a &lt;em&gt;much&lt;/em&gt; better book than the first edition. Again, it&amp;#39;s not quite my preferred style, but for readers who like that sort of thing, it&amp;#39;s a much better option than Fluent C# at the moment, and one I&amp;#39;m happy to recommend (with the express caveat of getting the second edition).&lt;/p&gt;  &lt;p&gt;At the same time, reading Fluent C# (and particularly thinking about its debugger-first approach) has set me something of a challenge. You see, I&amp;#39;ve mostly avoided writing for new programmers so far - but I feel it&amp;#39;s &lt;em&gt;really&lt;/em&gt; important to get folks off on the right foot, and I&amp;#39;d like to have a stab at it. In particular, I would like to see if it&amp;#39;s possible to write an introductory text which teaches C# using unit tests wherever possible... but without being dry. Can we have a &amp;quot;fun&amp;quot; but accurate book, which tries to teach C# from scratch without giving the impression that user interfaces are the be-all and end-all of programming? Can I write in a way which is more personal but doesn&amp;#39;t feel artificial? I can&amp;#39;t see myself starting such a project any time in the next year, but maybe some time in 2013... Watch this space. In the meantime, I&amp;#39;ll keep an eye out for any more introductory books which might be more promising than Fluent C#.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1803256" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/wg2DJGKWqNY" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Book+reviews/default.aspx">Book reviews</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/12/05/book-review-fluent-c-rebecca-riordan-sams.aspx</feedburner:origLink></item><item><title>Eduasync part 17: unit testing</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/DnRbqgbMyKE/eduasync-part-17-unit-testing.aspx</link><pubDate>Fri, 25 Nov 2011 21:46:45 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802928</guid><dc:creator>skeet</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1802928</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1802928</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/11/25/eduasync-part-17-unit-testing.aspx#comments</comments><description>&lt;p&gt;In the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/11/22/eduasync-part-16-example-of-composition-majority-voting.aspx"&gt;last post&lt;/a&gt; I showed a method to implement &amp;quot;majority voting&amp;quot; for tasks, allowing a result to become available as soon as possible. At the end, I mentioned that I was reasonably confident that it worked because of the unit tests... but I didn&amp;#39;t show the tests themselves. I felt they deserved their own post, as there&amp;#39;s a bigger point here: &lt;em&gt;it&amp;#39;s possible to unit test async code&lt;/em&gt;. At least sometimes.&lt;/p&gt;  &lt;p&gt;Testing code involving asynchrony is generally a pain. Introducing the exact order of events that you want is awkward, as is managing the threading within tests. With a few benefits with async methods:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We know that the async method itself will only execute in a single thread at a time &lt;/li&gt;    &lt;li&gt;We can control the thread in which the async method will execute, &lt;em&gt;if&lt;/em&gt; it doesn&amp;#39;t configure its awaits explicitly &lt;/li&gt;    &lt;li&gt;Assuming the async method returns Task or Task&amp;lt;T&amp;gt;, we can check whether or not it&amp;#39;s finished &lt;/li&gt;    &lt;li&gt;Between Task&amp;lt;T&amp;gt; and TaskCompletionSource&amp;lt;T&amp;gt;, we have a way of injecting tasks that we understand &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now in our sample method we have the benefit of passing in the tasks that will be awaited - but assuming you&amp;#39;re using some reasonably testable API to fetch any awaitables within your async method, you should be okay. (Admittedly in the current .NET framework that excludes rather a lot of classes... but the synchronous versions of those calls are also generally hard to test too.)&lt;/p&gt;  &lt;h3&gt;The plan&lt;/h3&gt;  &lt;p&gt;For our majority tests, we want to be able to see what happens in various scenarios, with tasks completing at different times and in different ways. Looking at the &lt;a href="http://code.google.com/p/eduasync/source/browse/src/MajorityVoting.Tests/WhenMajorityTest.cs"&gt;test cases I&amp;#39;ve implemented&lt;/a&gt; I have the following tests:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;NullSequenceOfTasks &lt;/li&gt;    &lt;li&gt;EmptySequenceOfTasks &lt;/li&gt;    &lt;li&gt;NullReferencesWithinSequence &lt;/li&gt;    &lt;li&gt;SimpleSuccess &lt;/li&gt;    &lt;li&gt;InputOrderIsIrrelevant &lt;/li&gt;    &lt;li&gt;MajorityWithSomeDisagreement &lt;/li&gt;    &lt;li&gt;MajorityWithFailureTask &lt;/li&gt;    &lt;li&gt;EarlyFailure &lt;/li&gt;    &lt;li&gt;NoMajority &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I&amp;#39;m not going to claim this is a &lt;em&gt;comprehensive&lt;/em&gt; set of possible tests - it&amp;#39;s a proof of concept more than anything else. Let&amp;#39;s take one test as an example: MajorityWithFailureTask. The aim of this is to pass three tasks (of type Task&amp;lt;string&amp;gt;) into the method. One will give a result of &amp;quot;x&amp;quot;, the second will fail with an exception, and the third will also give a result of &amp;quot;x&amp;quot;. The events will occur in that order, and only when all three results are in should the returned task complete, at which point it will also have a success result of &amp;quot;x&amp;quot;.&lt;/p&gt;  &lt;p&gt;So, the tricky bit (compared with normal testing) is introducing the timing. We want to make it &lt;em&gt;appear&lt;/em&gt; as if tasks are completing in a particular order, at predetermined times, so we can check the state of the result between events.&lt;/p&gt;  &lt;h3&gt;Introducing the TimeMachine class&lt;/h3&gt;  &lt;p&gt;Okay, so it&amp;#39;s a silly name. But the basic idea is to have something to control the logical flow of time through our test. We&amp;#39;re going to ask the TimeMachine to &lt;em&gt;provide&lt;/em&gt; us with tasks which will act in a particular way at a given time, and then when we&amp;#39;ve started our async method we can then ask it to move time forward, letting the tasks complete as they go. It&amp;#39;s probably best to look at the code for MajorityWithFailureTask first, and then see what the implementation of TimeMachine looks like. Here&amp;#39;s the test:&lt;/p&gt;  &lt;div class="code"&gt;[Test]    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; MajorityWithFailureTask()     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; timeMachine = &lt;span class="Keyword"&gt;new&lt;/span&gt; TimeMachine();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Second task gives a different result&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; task1 = timeMachine.AddSuccessTask(1, &lt;span class="String"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; task2 = timeMachine.AddFaultingTask&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;&amp;gt;(2, &lt;span class="Keyword"&gt;new&lt;/span&gt; Exception(&lt;span class="String"&gt;&amp;quot;Bang!&amp;quot;&lt;/span&gt;));     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; task3 = timeMachine.AddSuccessTask(3, &lt;span class="String"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; resultTask = MoreTaskEx.WhenMajority(task1, task2, task3);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Assert.IsFalse(resultTask.IsCompleted);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Only one result so far - no consensus&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; timeMachine.AdvanceTo(1);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Assert.IsFalse(resultTask.IsCompleted);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Second result is a failure&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; timeMachine.AdvanceTo(2);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Assert.IsFalse(resultTask.IsCompleted);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Third result gives majority verdict&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; timeMachine.AdvanceTo(3);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Assert.AreEqual(TaskStatus.RanToCompletion, resultTask.Status);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Assert.AreEqual(&lt;span class="String"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;, resultTask.Result);     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;As you can see, there are two types of method:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;AddSuccessTask / AddFaultingTask / AddCancelTask (not used here) - these all take the time at which they&amp;#39;re going to complete as their first parameter, and the method name describes the state they&amp;#39;ll reach on completion. The methods &lt;em&gt;return&lt;/em&gt; the task created by the time machine, ready to pass into the production code we&amp;#39;re testing. &lt;/li&gt;    &lt;li&gt;AdvanceTo / AdvanceBy (not used here) - make the time machine &amp;quot;advance time&amp;quot;, completing pre-programmed tasks as it goes. When those tasks complete, any continuations attached to them also execute, which is how the whole thing hangs together. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now forcing tasks to complete is actually pretty simple, if you build them out of TaskCompletionSource&amp;lt;T&amp;gt; to start with. So all we need to do is keep our tasks in &amp;quot;time&amp;quot; order (which I achieve with SortedList), and then when we&amp;#39;re asked to advance time we move through the list and take the appropriate action for all the tasks which &lt;em&gt;weren&amp;#39;t&lt;/em&gt; completed before, but are now. I represent the &amp;quot;appropriate action&amp;quot; as a simple Action, which is built with a lambda expression from each of the Add methods. It&amp;#39;s really simple:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; TimeMachine    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; currentTime = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; SortedList&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, Action&amp;gt; actions = &lt;span class="Keyword"&gt;new&lt;/span&gt; SortedList&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;, Action&amp;gt;();    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; CurrentTime { get { &lt;span class="Statement"&gt;return&lt;/span&gt; currentTime; } }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; AdvanceBy(&lt;span class="ValueType"&gt;int&lt;/span&gt; time)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; AdvanceTo(currentTime + time);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; AdvanceTo(&lt;span class="ValueType"&gt;int&lt;/span&gt; time)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Okay, not terribly efficient, but it&amp;#39;s simple.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; entry &lt;span class="Statement"&gt;in&lt;/span&gt; actions)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (entry.Key &amp;gt; currentTime &amp;amp;&amp;amp; entry.Key &amp;lt;= time)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; entry.Value();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; currentTime = time;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; Task&amp;lt;T&amp;gt; AddSuccessTask&amp;lt;T&amp;gt;(&lt;span class="ValueType"&gt;int&lt;/span&gt; time, T result)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TaskCompletionSource&amp;lt;T&amp;gt; tcs = &lt;span class="Keyword"&gt;new&lt;/span&gt; TaskCompletionSource&amp;lt;T&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; actions[time] = () =&amp;gt; tcs.SetResult(result);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; tcs.Task;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; Task&amp;lt;T&amp;gt; AddCancelTask&amp;lt;T&amp;gt;(&lt;span class="ValueType"&gt;int&lt;/span&gt; time)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TaskCompletionSource&amp;lt;T&amp;gt; tcs = &lt;span class="Keyword"&gt;new&lt;/span&gt; TaskCompletionSource&amp;lt;T&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; actions[time] = () =&amp;gt; tcs.SetCanceled();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; tcs.Task;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; Task&amp;lt;T&amp;gt; AddFaultingTask&amp;lt;T&amp;gt;(&lt;span class="ValueType"&gt;int&lt;/span&gt; time, Exception e)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TaskCompletionSource&amp;lt;T&amp;gt; tcs = &lt;span class="Keyword"&gt;new&lt;/span&gt; TaskCompletionSource&amp;lt;T&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; actions[time] = () =&amp;gt; tcs.SetException(e);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; tcs.Task;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Okay, that&amp;#39;s a fair amount of code for a blog posts (and yes, it could do with some doc comments etc!) but considering that it makes life testable, it&amp;#39;s pretty simple.&lt;/p&gt;  &lt;p&gt;So, is that it?&lt;/p&gt;  &lt;h3&gt;It works on my machine... with my test runner... in simple cases...&lt;/h3&gt;  &lt;p&gt;When I first ran the tests using TimeMachine, they worked almost immediately. This didn&amp;#39;t surprise me nearly as much as it should have done. You see, when the tests execute, they use async/await in the normal way - which means the continuations are scheduled on &amp;quot;the current task scheduler&amp;quot;. &lt;em&gt;I have no idea what the current task scheduler is in unit tests&lt;/em&gt;. Or rather, it feels like something which is implementation specific. It could easily have worked when running the tests from ReSharper, but not from NCrunch, or not from the command line NUnit test runner.&lt;/p&gt;  &lt;p&gt;As it happens, I believe all of these run tests on thread pool threads with no task scheduler allocated, which means that the continuation is attached to the task to complete &amp;quot;in-line&amp;quot; - so when the TimeMachine sets the result on a TaskCompletionSource, the continuations execute before that call returns. That means everything happens on one thread, with no ambiguity or flakiness - yay!&lt;/p&gt;  &lt;p&gt;However, there are two problems:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The words &amp;quot;I believe&amp;quot; aren&amp;#39;t exactly confidence-inspiring when it comes to testing that your software works correctly.&lt;/li&gt;    &lt;li&gt;Our majority voting code only ever sees one completed task at a time - we&amp;#39;re not testing the situation where several tasks complete so quickly together that the continuation doesn&amp;#39;t get chance to run before they&amp;#39;ve all finished.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Both of these are solvable with a custom TaskScheduler or SynchronizationContext. Without diving into the docs, I&amp;#39;m not sure yet which I&amp;#39;ll need, but the aim will be:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Make TimeMachine implement IDisposable&lt;/li&gt;    &lt;li&gt;In the constructor, set the current SynchronizationContext (or TaskScheduler) to a custom one having remembered what the previous one was&lt;/li&gt;    &lt;li&gt;On disposal, reset the context&lt;/li&gt;    &lt;li&gt;Make the custom scheduler keep a queue of jobs, such that when we&amp;#39;re asked to advance to time T, we complete &lt;em&gt;all&lt;/em&gt; the appropriate tasks but don&amp;#39;t execute any continuations, then we execute all the pending continuations.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I don&amp;#39;t yet know how hard it will be, but hopefully the &lt;a href="http://code.msdn.microsoft.com/ParExtSamples"&gt;Parallel Extensions Samples&lt;/a&gt; will help me.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;I&amp;#39;m not going to claim this is &amp;quot;the&amp;quot; way of unit testing asynchronous methods. It&amp;#39;s clearly a proof-of-concept implementation of what can only be called a &amp;quot;test framework&amp;quot; in the loosest possible sense. However, I hope it gives &lt;em&gt;an&lt;/em&gt; example of a path we might take. I&amp;#39;m looking forward to seeing what others come up with, along with rather more polished implementations.&lt;/p&gt;  &lt;p&gt;Next time, I&amp;#39;m going to shamelessly steal an idea that a reader mailed me (with permission, of course). It&amp;#39;s insanely cool, simple and yet slightly brain-bending, and I suspect will handy in many situations. Love it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802928" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/DnRbqgbMyKE" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+5/default.aspx">C# 5</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/async/default.aspx">async</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx">Eduasync</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/11/25/eduasync-part-17-unit-testing.aspx</feedburner:origLink></item><item><title>Eduasync part 16: Example of composition: majority voting</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/6Sacmt2nzms/eduasync-part-16-example-of-composition-majority-voting.aspx</link><pubDate>Tue, 22 Nov 2011 23:18:41 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802817</guid><dc:creator>skeet</dc:creator><slash:comments>4</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1802817</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1802817</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/11/22/eduasync-part-16-example-of-composition-majority-voting.aspx#comments</comments><description>&lt;p&gt;Note: For the rest of this series, I&amp;#39;ll be veering away from the original purpose of the project (investigating what the compiler is up to) in favour of discussing the feature itself. As such, I&amp;#39;ve added a requirement for AsyncCtpLib.dll - but due to potential distribution restrictions, I&amp;#39;ve felt it safest &lt;em&gt;not&lt;/em&gt; to include that in the source repository. If you&amp;#39;re running this code yourself, you&amp;#39;ll need to copy the DLL from your installation location into the Eduasync\lib directory before it will build - or change each reference to it.&lt;/p&gt;  &lt;p&gt;One of the things I &lt;em&gt;love&lt;/em&gt; about async is the compositional aspect. This is partly due to the way that the Task Parallel Library encourages composition to start with, but async/await makes it even easier by building the tasks for you. In the next few posts I&amp;#39;ll talk about a few examples of interesting building blocks. I wouldn&amp;#39;t be surprised to see an open source library with a &lt;em&gt;proper&lt;/em&gt; implementation of some of these ideas (Eduasync is &lt;em&gt;not&lt;/em&gt; designed for production usage) whether from Microsoft or a third party.&lt;/p&gt;  &lt;p&gt;In &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FMajorityVoting"&gt;project 26 of Eduasync&lt;/a&gt;, I&amp;#39;ve implemented &amp;quot;majority voting&amp;quot; via composition. The basic idea is simple, and the motivation should be reasonably obvious in this day and age of redundant services. You have (say) five different tasks which are meant to be computing the same thing. As soon as you have a single answer which the majority of the tasks agree on, the code which needs the result can continue. If the tasks disagree, or fail (or a combination leading to no single successful majority result), the overall result is failure too.&lt;/p&gt;  &lt;p&gt;My personal experience with services requiring a majority of operations to return is with &lt;a href="http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en//pubs/archive/36971.pdf"&gt;Megastore&lt;/a&gt;, a storage system we use at Google. I&amp;#39;m not going to pretend to understand half of the details of how Megastore works, and I&amp;#39;m certainly not about to reveal any confidential information about its internals or indeed how we use it, but basically when discussing it with colleagues at around the time that async was announced, I contemplated what a handy feature async would be when implementing a Megastore client. It could also be used in systems where each calculation is performed in triplicate to guard against rogue errors - although I suspect the chances of those systems being implemented in C# are pretty small.&lt;/p&gt;  &lt;p&gt;It&amp;#39;s worth mentioning that the implementation here &lt;em&gt;wouldn&amp;#39;t&lt;/em&gt; be appropriate for something like a stock price service, where the result can change rapidly and you may be happy to tolerate a &lt;em&gt;small&lt;/em&gt; discrepancy, within some bounds.&lt;/p&gt;  &lt;h3&gt;The API&lt;/h3&gt;  &lt;p&gt;Here&amp;#39;s the signatures of the methods we&amp;#39;ll implement:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Task&amp;lt;T&amp;gt; WhenMajority&amp;lt;T&amp;gt;(&lt;span class="MethodParameter"&gt;params&lt;/span&gt; Task&amp;lt;T&amp;gt;[] tasks)     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Task&amp;lt;T&amp;gt; WhenMajority&amp;lt;T&amp;gt;(IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; tasks) &lt;/div&gt;  &lt;p&gt;Obviously the first just delegates to the second, but it&amp;#39;s helpful to have both forms, so that we can pass in a few tasks in an ad hoc manner with the first overload, or a LINQ-generated sequence of tasks with the second.&lt;/p&gt;  &lt;p&gt;The name is a little odd - it&amp;#39;s meant to match WhenAll and WhenAny, but I&amp;#39;m sure there are better options. I&amp;#39;m not terribly interested in that at the moment.&lt;/p&gt;  &lt;p&gt;It&amp;#39;s easy to use within an async method:&lt;/p&gt;  &lt;div class="code"&gt;Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; firstTask = firstServer.ComputeSomethingAsync(input);     &lt;br /&gt;Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; secondTask = selectServer.ComputeSomethingAsync(input);     &lt;br /&gt;Task&amp;lt;&lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; thirdTask = thirdServer.ComputeSomethingAsync(input);     &lt;br /&gt;    &lt;br /&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; result = &lt;span class="Modifier"&gt;await&lt;/span&gt; MoreTaskEx.WhenMajority(firstTask, secondTask, thirdTask); &lt;/div&gt;  &lt;p&gt;Or using the LINQ-oriented overload:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Linq"&gt;var&lt;/span&gt; tasks = servers.Select(server =&amp;gt; server.ComputeSomethingAsync(input));     &lt;br /&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; result = &lt;span class="Modifier"&gt;await&lt;/span&gt; MoreTaskEx.WhenMajority(tasks); &lt;/div&gt;  &lt;p&gt;Of course we could add an extension method (dropping the When prefix as it doesn&amp;#39;t make as much sense there, IMO):&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="ValueType"&gt;int&lt;/span&gt; result = &lt;span class="Modifier"&gt;await&lt;/span&gt; servers.Select(server =&amp;gt; server.ComputeSomethingAsync(input))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; .MajorityAsync(); &lt;/div&gt;  &lt;p&gt;The fact that we&amp;#39;ve stayed within the Task&amp;lt;T&amp;gt; model is what makes it all work so smoothly. We couldn&amp;#39;t easily express the same API for other awaitable types &lt;em&gt;in general&lt;/em&gt; although we could do it for any other &lt;em&gt;specific&lt;/em&gt; awaitable type of course. It&amp;#39;s possible that it would work using dynamic, but I&amp;#39;d rather avoid that :) Let&amp;#39;s implement it now.&lt;/p&gt;  &lt;h3&gt;Implementation&lt;/h3&gt;  &lt;p&gt;There are two parts to the implementation, in the same way that we implemented LINQ operators in &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx"&gt;Edulinq&lt;/a&gt; - and for the same reason. We want to go bang &lt;em&gt;immediately&lt;/em&gt; if there are any clear input violations - such as the sequence of tasks being null or empty. This is in line with the &lt;a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;amp;id=19957"&gt;Task-based Asynchronous Pattern white paper&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;An asynchronous method should only directly raise an exception to be thrown out of the &lt;i&gt;MethodName&lt;/i&gt;Async call in response to a &lt;i&gt;usage&lt;/i&gt; error*. For all other errors, exceptions occurring during the execution of an asynchronous method should be assigned to the returned Task. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now it occurs to me that we don&amp;#39;t &lt;em&gt;really&lt;/em&gt; need to do this in two separate methods (one for precondition checking, one for real work). We &lt;em&gt;could&lt;/em&gt; create an async lambda expression of type Func&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;, and make the method just return the result of invoking it - but I don&amp;#39;t think that would be great in terms of readability.&lt;/p&gt;  &lt;p&gt;So, the first part of the implementation performing validation is really simple:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Task&amp;lt;T&amp;gt; WhenMajority&amp;lt;T&amp;gt;(&lt;span class="MethodParameter"&gt;params&lt;/span&gt; Task&amp;lt;T&amp;gt;[] tasks)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; WhenMajority((IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;) tasks);     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt; Task&amp;lt;T&amp;gt; WhenMajority&amp;lt;T&amp;gt;(IEnumerable&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; tasks)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (tasks == &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span class="String"&gt;&amp;quot;tasks&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; taskList = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;(tasks);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (taskList.Count == 0)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="String"&gt;&amp;quot;Empty sequence of tasks&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; task &lt;span class="Statement"&gt;in&lt;/span&gt; taskList)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (task == &lt;span class="Keyword"&gt;null&lt;/span&gt;)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ArgumentException(&lt;span class="String"&gt;&amp;quot;Null task in sequence&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; WhenMajorityImpl(taskList);     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;The interesting part is obviously in WhenMajorityImpl. It&amp;#39;s &lt;em&gt;mildly&lt;/em&gt; interesting to note that I create a copy of the sequence passed in to start with - I know I&amp;#39;ll need it in a fairly concrete form, so it&amp;#39;s appropriate to remove any laziness at this point.&lt;/p&gt;  &lt;p&gt;So, here&amp;#39;s WhenMajorityImpl, which I&amp;#39;ll then explain:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt; Task&amp;lt;T&amp;gt; WhenMajorityImpl&amp;lt;T&amp;gt;(List&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; tasks)    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Need a real majority - so for 4 or 5 tasks, must have 3 equal results.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; majority = (tasks.Count / 2) + 1;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; failures = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; bestCount = 0;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Dictionary&amp;lt;T, &lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt; results = &lt;span class="Keyword"&gt;new&lt;/span&gt; Dictionary&amp;lt;T, &lt;span class="ValueType"&gt;int&lt;/span&gt;&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; List&amp;lt;Exception&amp;gt; exceptions = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;Exception&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;while&lt;/span&gt; (&lt;span class="Keyword"&gt;true&lt;/span&gt;)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; TaskEx.WhenAny(tasks);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;var&lt;/span&gt; newTasks = &lt;span class="Keyword"&gt;new&lt;/span&gt; List&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;foreach&lt;/span&gt; (&lt;span class="Linq"&gt;var&lt;/span&gt; task &lt;span class="Statement"&gt;in&lt;/span&gt; tasks)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;switch&lt;/span&gt; (task.Status)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;case&lt;/span&gt; TaskStatus.Canceled:    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; failures++;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;case&lt;/span&gt; TaskStatus.Faulted:    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; failures++;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; exceptions.Add(task.Exception.Flatten());    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;case&lt;/span&gt; TaskStatus.RanToCompletion:    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; count;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Doesn&amp;#39;t matter whether it was there before or not - we want 0 if not anyway&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; results.TryGetValue(task.Result, &lt;span class="MethodParameter"&gt;out&lt;/span&gt; count);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; count++;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (count &amp;gt; bestCount)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bestCount = count;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (count &amp;gt;= majority)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt; task.Result;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; results[task.Result] = count;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;default&lt;/span&gt;:    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Keep going next time. may not be appropriate for Created&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; newTasks.Add(task);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;break&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// The new list of tasks to wait for&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; tasks = newTasks;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// If we can&amp;#39;t possibly work, bail out.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (tasks.Count + bestCount &amp;lt; majority)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; AggregateException(&lt;span class="String"&gt;&amp;quot;No majority result possible&amp;quot;&lt;/span&gt;, exceptions);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;I should warn you that this &lt;em&gt;isn&amp;#39;t&lt;/em&gt; a particularly efficient implementation - it was just one I wrote until it worked. The basic steps are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Work out how many results make a majority, so we know when to stop&lt;/li&gt;    &lt;li&gt;Keep track of how many &amp;quot;votes&amp;quot; our most commonly-returned result has, along with the counts of &lt;em&gt;all&lt;/em&gt; the votes&lt;/li&gt;    &lt;li&gt;Repeatedly:&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Wait (asynchronously) for &lt;em&gt;at least&lt;/em&gt; of the remaining tasks to finish (many may finish &amp;quot;at the same time&amp;quot;)&lt;/li&gt;      &lt;li&gt;Start a new list of &amp;quot;tasks we&amp;#39;re going to wait for next time&amp;quot;&lt;/li&gt;      &lt;li&gt;Process each task in the current list, taking an action on each state:&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;If it&amp;#39;s been cancelled, we&amp;#39;ll treat that as a failure (we could potentially treat &amp;quot;the majority have been cancelled&amp;quot; as a cancellation, but for the moment a failure is good enough)&lt;/li&gt;        &lt;li&gt;If it&amp;#39;s faulted, we&amp;#39;ll add the exception to the list of exceptions, so that if the overall result ends up as failure, we can throw an AggregateException with all of the individual exceptions&lt;/li&gt;        &lt;li&gt;If it&amp;#39;s finished successfully, we&amp;#39;ll check the result:&lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;Add 1 to the count for that result (the dictionary will use the default comparer for the result type, which we assume is good enough)&lt;/li&gt;          &lt;li&gt;If this is greater than the previous &amp;quot;winner&amp;quot; (which could be for the same result), check for it being actually an overall majority, and return if so.&lt;/li&gt;       &lt;/ul&gt;        &lt;li&gt;If it&amp;#39;s still running (or starting), add it to the new task list&lt;/li&gt;     &lt;/ul&gt;      &lt;li&gt;Check whether enough tasks have failed - or given different results - so ensure that a majority is now impossible. If so, throw an AggregateException to say so. This &lt;em&gt;may&lt;/em&gt; have some exceptions, but it may not (if there are three tasks which gave different results, none of them actually &lt;em&gt;failed&lt;/em&gt;)&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;Each iteration of the &amp;quot;repeatedly&amp;quot; will have a smaller list to check than before, so we&amp;#39;ll definitely terminate at some point.&lt;/p&gt;  &lt;p&gt;I mentioned that it&amp;#39;s inefficient. In particular, we&amp;#39;re ignoring the fact that WhenAny returns a Task&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt;, so awaiting that will actually tell us &lt;em&gt;a&lt;/em&gt; task which has finished. We don&amp;#39;t need to loop over the whole collection at that point - we could just remove that single task from the collection. We could do that efficiently if we kept a Dictionary&amp;lt;Task&amp;lt;T&amp;gt;, LinkedListNode&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; and a LinkedList&amp;lt;Task&amp;lt;T&amp;gt;&amp;gt; - we&amp;#39;d just look up the task which had completed in the dictionary, remove its node from the list, and remove the entry from the dictionary. We wouldn&amp;#39;t need to create a new collection each time, or iterate through all of the old one. However, that&amp;#39;s a job for another day... as is allowing a cancellation token to be passed in, and a custom equality comparer.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;So we can make this implementation smarter and more flexible, certainly - but it&amp;#39;s not insanely tricky to write. I&amp;#39;m &lt;em&gt;reasonably&lt;/em&gt; confident that it works, too - as I have unit tests for it. They&amp;#39;ll come in the next part. The important point&amp;#160; from this post is that by sticking within the Task&amp;lt;T&amp;gt; world, we can &lt;em&gt;reasonably easily&lt;/em&gt; create building blocks to allow for composition of asynchronous operations. While it would be nice to have someone more competent than myself write a bullet-proof, efficient implementation of this operation, I wouldn&amp;#39;t feel too unhappy using a homegrown one in production. The same could &lt;em&gt;not&lt;/em&gt; have been said pre-async/await. I just wouldn&amp;#39;t have had a chance of getting it right.&lt;/p&gt;  &lt;p&gt;Next up - the unit tests for this code, in which I introduce the TimeMachine class.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802817" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/6Sacmt2nzms" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/async/default.aspx">async</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx">Eduasync</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/11/22/eduasync-part-16-example-of-composition-majority-voting.aspx</feedburner:origLink></item><item><title>Eduasync part 15: implementing COMEFROM with a horrible hack</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/RPulVO5m5sM/eduasync-part-15-implementing-comefrom-with-a-horrible-hack.aspx</link><pubDate>Fri, 11 Nov 2011 22:15:11 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1802363</guid><dc:creator>skeet</dc:creator><slash:comments>6</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1802363</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1802363</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/11/11/eduasync-part-15-implementing-comefrom-with-a-horrible-hack.aspx#comments</comments><description>&lt;p&gt;Ages ago when I wrote my &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/06/29/eduasync-part-14-data-passing-in-coroutines.aspx"&gt;previous Eduasync post&lt;/a&gt;, I said we&amp;#39;d look at a pipeline model of coroutines. I&amp;#39;ve decided to skip that, as I &lt;em&gt;do&lt;/em&gt; want to cover the topic of this post, and I&amp;#39;ve got some more &amp;quot;normal&amp;quot; async ideas to write about too. If you want to look at the pipeline coroutines code, it&amp;#39;s &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FPipelineCoroutines"&gt;project 20&lt;/a&gt; in the source repository. Have fun, and don&amp;#39;t blame me if you get confused reading it - so do I.&lt;/p&gt;  &lt;p&gt;The code I &lt;em&gt;am&lt;/em&gt; going to write about is horrible too. It&amp;#39;s almost as tricky to understand, and it does &lt;em&gt;far&lt;/em&gt; nastier things. Things that the C# 5 specification explicitly says you shouldn&amp;#39;t do.&lt;/p&gt;  &lt;p&gt;If it makes you feel any better when your head hurts reading this code, spare a thought for me - I haven&amp;#39;t looked at it in over six months, and &lt;em&gt;I&lt;/em&gt; don&amp;#39;t have a blog post explaining how it&amp;#39;s meant to work. I just have almost entirely uncommented code which is &lt;em&gt;designed&lt;/em&gt; to be hard to understand (in terms of the main program flow).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;On no account should any code like this ever be used for anything remotely serious.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;With that health warning out of the way, let&amp;#39;s have a look at it...&lt;/p&gt;  &lt;h3&gt;COMEFROM at the caller level&lt;/h3&gt;  &lt;p&gt;The idea is to implement the &lt;a href="http://en.wikipedia.org/wiki/COMEFROM"&gt;COMEFROM&lt;/a&gt; control structure, which is sort of the opposite of GOTO (or in my implementation, more of a GOSUB). There are two operations, effectively:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;ComeFrom(label): Register interest in a particular label. &lt;/li&gt;    &lt;li&gt;Label(label): If anyone has registered interested in the given label, keep going from their registration point (which will be within a method), then continue from where we left off afterwards. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In some senses it&amp;#39;s a little like the observer pattern, with labels taking the place of events. However, it looks entirely different and is &lt;em&gt;much&lt;/em&gt; harder to get your head round, because instead of having a nicely-encapsulated action which is subscribed to an event, we just have a ComeFrom call which lets us jump back into a method somewhat arbitrarily.&lt;/p&gt;  &lt;p&gt;I have two implementations, in &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FComeFromCoroutines"&gt;project 22&lt;/a&gt; and &lt;a href="http://code.google.com/p/eduasync/source/browse/#hg%2Fsrc%2FStateSavingComeFrom"&gt;project 23&lt;/a&gt; in source control. Project 22 is almost sane; a little funky, but not too bad. Project 23 is where the fun really happens. In addition to the operations listed above, there&amp;#39;s an Execute operation which is sort of an implementation detail - it allows an async method containing ComeFrom calls to be executed without returning earlier than we might want.&lt;/p&gt;  &lt;p&gt;Let&amp;#39;s look at some code and the output, and try to work out what&amp;#39;s going on.&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Program     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Main(&lt;span class="ReferenceType"&gt;string&lt;/span&gt;[] args)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Coordinator coordinator = &lt;span class="Keyword"&gt;new&lt;/span&gt; Coordinator(SimpleEntryPoint);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.Start();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; SimpleEntryPoint(Coordinator coordinator)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; coordinator.Execute(SimpleOtherMethod);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;First call to Label(x)&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; coordinator.Label(&lt;span class="String"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Second call to Label(x)&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; coordinator.Label(&lt;span class="String"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Registering interesting in y&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;bool&lt;/span&gt; firstTime = &lt;span class="Keyword"&gt;true&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; coordinator.ComeFrom(&lt;span class="String"&gt;&amp;quot;y&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;After ComeFrom(y). FirstTime={0}&amp;quot;&lt;/span&gt;, firstTime);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (firstTime)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; firstTime = &lt;span class="Keyword"&gt;false&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; coordinator.Label(&lt;span class="String"&gt;&amp;quot;y&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Finished&amp;quot;&lt;/span&gt;);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;static&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;async&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; SimpleOtherMethod(Coordinator coordinator)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;Start of SimpleOtherMethod&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="ValueType"&gt;int&lt;/span&gt; count = 0;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;await&lt;/span&gt; coordinator.ComeFrom(&lt;span class="String"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;);     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(&lt;span class="String"&gt;&amp;quot;After ComeFrom x in SimpleOtherMethod. count={0}. Returning.&amp;quot;&lt;/span&gt;,     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; count);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; count++;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;}&lt;/div&gt;  &lt;p&gt;The reason for the &amp;quot;Simple&amp;quot; prefix on the method names is that there&amp;#39;s another example in the same file, with a more complex control flow.&lt;/p&gt;  &lt;p&gt;Here&amp;#39;s the output - then we can look at why we&amp;#39;re getting it...&lt;/p&gt;  &lt;div class="output"&gt;Start of SimpleOtherMethod    &lt;br /&gt;After ComeFrom x in SimpleOtherMethod. count=0. Returning.     &lt;br /&gt;First call to Label(x)     &lt;br /&gt;After ComeFrom x in SimpleOtherMethod. count=1. Returning.     &lt;br /&gt;Second call to Label(x)     &lt;br /&gt;After ComeFrom x in SimpleOtherMethod. count=2. Returning.     &lt;br /&gt;Registering interesting in y     &lt;br /&gt;After ComeFrom(y). FirstTime=True     &lt;br /&gt;After ComeFrom(y). FirstTime=False     &lt;br /&gt;Finished &lt;/div&gt;  &lt;p&gt;So, the control flow is a bit like this:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Start SimpleEntryPoint      &lt;ul&gt;       &lt;li&gt;Call into SimpleOtherMethod          &lt;ul&gt;           &lt;li&gt;Log &amp;quot;Start of SimpleOtherMethod&amp;quot; &lt;/li&gt;            &lt;li&gt;Initialize the &amp;quot;count&amp;quot; variable with value 0 &lt;/li&gt;            &lt;li&gt;Register interest in x; ComeFrom remembers the continuation &lt;em&gt;but keeps going&lt;/em&gt;. &lt;/li&gt;            &lt;li&gt;Log &amp;quot;After ComeFrom x in SimpleOtherMethod. count=0. Returning.&amp;quot; &lt;/li&gt;            &lt;li&gt;Increment count to 1. &lt;/li&gt;            &lt;li&gt;Return. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Return takes us back to SimpleEntryPoint... &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Log &amp;quot;First call to Label(x)&amp;quot; &lt;/li&gt;    &lt;li&gt;Call Label(&amp;quot;x&amp;quot;)...      &lt;ul&gt;       &lt;li&gt;... which takes us back into SimpleOtherMethod (remember, the method we thought we&amp;#39;d finished executing?) just after ComeFrom          &lt;ul&gt;           &lt;li&gt;Log AfterComeFrom x in SimpleOtherMethod. count=1. Returning. &lt;/li&gt;            &lt;li&gt;Increment count to 2. &lt;/li&gt;            &lt;li&gt;Return. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Return takes us back to SimpleEntryPoint... &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Log &amp;quot;Second call to Label(x)&amp;quot; &lt;/li&gt;    &lt;li&gt;Call Label(&amp;quot;x&amp;quot;)...      &lt;ul&gt;       &lt;li&gt;... which takes us back into SimpleOtherMethod again          &lt;ul&gt;           &lt;li&gt;Log AfterComeFrom x in SimpleOtherMethod. count=2. Returning. &lt;/li&gt;            &lt;li&gt;Increment count to 3. &lt;/li&gt;            &lt;li&gt;Return. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Return takes us back to SimpleEntryPoint... &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Log &amp;quot;Registering interest in y&amp;quot; &lt;/li&gt;    &lt;li&gt;Initialize the &amp;quot;firstTime&amp;quot; variable with value true. &lt;/li&gt;    &lt;li&gt;Register interest in y; ComeFrom remembers the continuation and keeps going &lt;/li&gt;    &lt;li&gt;Log &amp;quot;After ComeFrom(y). FirstTime=True&amp;quot; &lt;/li&gt;    &lt;li&gt;Check the value of firstTime... It&amp;#39;s true, so:      &lt;ul&gt;       &lt;li&gt;Set firstTime to false &lt;/li&gt;        &lt;li&gt;Call Label(&amp;quot;y&amp;quot;) &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;... which takes us back to earlier in the method (just after ComeFrom), like a normal looping construct... &lt;/li&gt;    &lt;li&gt;Log &amp;quot;After ComeFrom(y). FirstTime=False&amp;quot; &lt;/li&gt;    &lt;li&gt;Check the value of firstTime... It&amp;#39;s false, so:      &lt;ul&gt;       &lt;li&gt;Log &amp;quot;Finished&amp;quot; &lt;/li&gt;        &lt;li&gt;Exit! &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Doing all of this has a few interesting challenges. Let&amp;#39;s look at them one at a time... and I would &lt;em&gt;strongly&lt;/em&gt; advise you not to try to pay too much attention to the details.&lt;/p&gt;  &lt;h3&gt;Noting a continuation and continuing regardless...&lt;/h3&gt;  &lt;p&gt;Just as a quick reminder before we get cracking, it&amp;#39;s worth remembering that &lt;em&gt;all&lt;/em&gt; of this is entirely synchronous, despite being implemented with async. There&amp;#39;s only a single user thread involved here. As with previous parts, we maintain a stack of actions to call, and basically keep calling from the top until we&amp;#39;re done - but the actions we call can create extra stack entries, of course.&lt;/p&gt;  &lt;p&gt;ComeFrom has unusual semantics in terms of async. We want to remember the continuation &lt;em&gt;and&lt;/em&gt; keep executing as if we didn&amp;#39;t need to wait. We can easily do one side or the other. If we wanted to just keep going without needing to know about the continuation, we could just return true from IsCompleted. If we just want to remember the continuation, we can make the awaiter&amp;#39;s IsCompleted property return false, and remember the continuation when it&amp;#39;s passed to OnCompleted. How do we do both?&lt;/p&gt;  &lt;p&gt;Well, effectively we want to remember the continuation and then call it immediately. But we can&amp;#39;t &lt;em&gt;just&lt;/em&gt; call it directly from OnCompleted, as otherwise each ComeFrom call would end up in a &amp;quot;real&amp;quot; execution stack from, whereas our execution stack is stored as a Stack&amp;lt;Action&amp;gt;. So instead, we need to remember the continuation and immediately put it at the top of the stack.&lt;/p&gt;  &lt;p&gt;However, that only works if as soon as the generated code returns from the async method containing the ComeFrom call, we go back into the state machine. If we&amp;#39;d just called SimpleOtherMethod directly in SimpleEntryPoint, we would have continued within SimpleEntryPoint with the new stack entry just waiting around. This is why we need the Executor method: that does exactly the same thing, effectively shuffling the stack around. When it&amp;#39;s given something to execute, it puts its own continuation on the action stack, &lt;em&gt;then&lt;/em&gt; the action it&amp;#39;s been asked to execute, then returns. The top level code will then pick up the original action, and we&amp;#39;re away.&lt;/p&gt;  &lt;p&gt;So, here&amp;#39;s the code for Execute, which is the simplest part of the coordinator:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; ExecuteAwaiter Execute(Action&amp;lt;Coordinator&amp;gt; action)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ExecuteAwaiter(() =&amp;gt; action(&lt;span class="Keyword"&gt;this&lt;/span&gt;), &lt;span class="Keyword"&gt;this&lt;/span&gt;);     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; ExecuteAwaiter     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Action action;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Coordinator coordinator;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt; ExecuteAwaiter(Action action, Coordinator coordinator)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.action = action;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.coordinator = coordinator;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; ExecuteAwaiter GetAwaiter()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;this&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Always yield&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;bool&lt;/span&gt; IsCompleted { get { &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;false&lt;/span&gt;; } }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; OnCompleted(Action callerContinuation)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// We want to execute the action continuation, then get back here,&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// allowing any extra continuations put on the stack *within* the action&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// to be executed.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.stack.Push(callerContinuation);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.stack.Push(action);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; GetResult()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;All the awaitables in this project return themselves as the awaiter - when you don&amp;#39;t need any other state, it&amp;#39;s an easy step to take.&lt;/p&gt;  &lt;p&gt;That&amp;#39;s all we need to say about Execute, but how exactly are we capturing the continuation in ComeFrom?&lt;/p&gt;  &lt;h3&gt;Capturing continuations&lt;/h3&gt;  &lt;p&gt;Once we&amp;#39;ve got the action stack shuffling under our belts, there are two more problems with ComeFrom:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;What happens if we ComeFrom the same label twice? &lt;/li&gt;    &lt;li&gt;How do we really capture a continuation? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The first point didn&amp;#39;t come up in the sample I&amp;#39;ve shown here, but it &lt;em&gt;does&lt;/em&gt; come up in the more complex example - imagine if SimpleOtherMethod had two ComeFrom calls; when we jump back to the first one, we&amp;#39;ll execute the second one again. I made a simple policy decision to only allow a single &amp;quot;return point&amp;quot; for any label - if a ComeFrom call tries to register the &lt;em&gt;existing &lt;/em&gt;continuation point for a label, we ignore it; otherwise we throw an exception. So we only need to care about a single continuation for any label, which makes life easier.&lt;/p&gt;  &lt;p&gt;The second point is trickier. If you remember back to earlier posts in this series, we saw that the state machine generated for async only really contains a single entry point (MoveNext) which is used for &lt;em&gt;all&lt;/em&gt; continuations. A variable in the state machine is responsible for remembering where we were within it between calls. So in order to really make the continuation remember the point at which it needs to continue, we need to remember that state. We need to store an object for the continuation, which contains the delegate to invoke, and the state of the state machine when we were first passed the continuation. I&amp;#39;ve created a class for this, unimaginatively called Continuation, which looks like this:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// This hack allows a continuation to be executed more than once,&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// contrary to the C# spec. It does this using reflection to store the&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// value of the &amp;quot;state&amp;quot; field within the generated class. NEVER, EVER, EVER&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// try to use this in real code. It&amp;#39;s purely for fun.&lt;/span&gt;     &lt;br /&gt;&lt;span class="XmlComment"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; Continuation : IEquatable&amp;lt;Continuation&amp;gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;int&lt;/span&gt; savedState;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;object&lt;/span&gt; target;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; FieldInfo field;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Action action;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt; Continuation(Action action)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; target = action.Target;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; field = target.GetType().GetField(&lt;span class="String"&gt;&amp;quot;&amp;lt;&amp;gt;1__state&amp;quot;&lt;/span&gt;, BindingFlags.Instance | BindingFlags.NonPublic);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; savedState = (&lt;span class="ValueType"&gt;int&lt;/span&gt;) field.GetValue(target);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.action = action;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; Execute()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; field.SetValue(target, savedState);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; action();     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Snip Equals/GetHashCode&lt;/span&gt;     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Yes, we use reflection to fish out the &amp;lt;&amp;gt;1__state variable initially, and poke the state machine with the same value when we next want to execute the continuation. All highly implementation-specific, of course.&lt;/p&gt;  &lt;p&gt;Now the ComeFrom method is reasonably straightforward - all we need is a dictionary mapping labels to continuations. Oh, and the same action stack shuffling as for Execute:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// In the coordinator&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Dictionary&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;, Continuation&amp;gt; labels = &lt;span class="Keyword"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="ReferenceType"&gt;string&lt;/span&gt;, Continuation&amp;gt;();     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; ComeFromAwaiter ComeFrom(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; label)     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; ComeFromAwaiter(label, &lt;span class="Keyword"&gt;this&lt;/span&gt;);     &lt;br /&gt;}     &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;struct&lt;/span&gt; ComeFromAwaiter     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;string&lt;/span&gt; label;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Coordinator coordinator;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt; ComeFromAwaiter(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; label, Coordinator coordinator)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.label = label;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.coordinator = coordinator;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; ComeFromAwaiter GetAwaiter()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;this&lt;/span&gt;;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// We *always* want to be given the continuation&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;bool&lt;/span&gt; IsCompleted { get { &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;false&lt;/span&gt;; } }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; OnCompleted(Action action)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Continuation newContinuation = &lt;span class="Keyword"&gt;new&lt;/span&gt; Continuation(action);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Continuation oldContinuation;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (!coordinator.labels.TryGetValue(label, &lt;span class="MethodParameter"&gt;out&lt;/span&gt; oldContinuation))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// First time coming from this label. Always succeeds.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.labels[label] = newContinuation;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;else&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Current semantics are to prohibit two different ComeFrom calls for the same label.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// An alternative would be to just replace the existing continuation with the new one,&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// in which case we wouldn&amp;#39;t need any of this - we could just use&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// coordinator.labels[label] = newContinuation;&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// unconditionally.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;if&lt;/span&gt; (!oldContinuation.Equals(newContinuation))     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;throw&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span class="String"&gt;&amp;quot;Additional continuation detected for label &amp;quot;&lt;/span&gt; + label);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Okay, we&amp;#39;ve seen this one before. Nothing to see here, move on.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// We actually want to continue from where we were: we&amp;#39;re only really marking the&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// ComeFrom point.&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.stack.Push(action);     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; GetResult()     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;There&amp;#39;s one interesting point here which is somewhat subtle, and screwed me up for a bit...&lt;/p&gt;  &lt;h3&gt;The default value of a struct is always valid...&lt;/h3&gt;  &lt;p&gt;You may have noticed that ComeFromAwaiter is a struct. That&amp;#39;s pretty unusual for me. However, it&amp;#39;s also &lt;em&gt;absolutely critical&lt;/em&gt;. Without it, we&amp;#39;d get a NullReferenceException when we execute the continuation the second time.&lt;/p&gt;  &lt;p&gt;Normally, the flow of async methods looks a bit like this, for an await expression taking the &amp;quot;long&amp;quot; route (i.e. IsCompleted is false):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Call GetAwaiter() and assign the result to an awaiter field &lt;/li&gt;    &lt;li&gt;Call IsCompleted (which returns false in this scenario) &lt;/li&gt;    &lt;li&gt;Set the state variable to remember where we&amp;#39;d got to &lt;/li&gt;    &lt;li&gt;Call OnCompleted &lt;/li&gt;    &lt;li&gt;Return &lt;/li&gt;    &lt;li&gt;... When we continue... &lt;/li&gt;    &lt;li&gt;Set state to 0 (running) &lt;/li&gt;    &lt;li&gt;Call GetResult() on the awaiter &lt;/li&gt;    &lt;li&gt;Set the awaiter field to default(&lt;em&gt;TypeOfAwaiter&lt;/em&gt;) &lt;/li&gt;    &lt;li&gt;Continue &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Now that&amp;#39;s fine when we&amp;#39;re only continuing &lt;em&gt;once&lt;/em&gt; - but if we need to jump into the middle of that sequence a second time, we&amp;#39;re going to call GetAwaiter() on the awaiter field &lt;em&gt;after it&amp;#39;s been set to the default value of the awaiter type&lt;/em&gt;. If the default value is null, we&amp;#39;ll go bang. So we &lt;em&gt;must&lt;/em&gt; use a struct.&lt;/p&gt;  &lt;p&gt;Fortunately, our GetResult() call doesn&amp;#39;t need any of the state in the awaiter - it&amp;#39;s &lt;em&gt;purely&lt;/em&gt; there to satisfy the normal flow of things. So we&amp;#39;re quite happy with a &amp;quot;default&amp;quot; ComeFrom awaiter.&lt;/p&gt;  &lt;h3&gt;Finally, labels...&lt;/h3&gt;  &lt;p&gt;We&amp;#39;ve now done all the hard work. The final piece of the puzzle is Label, which &lt;em&gt;just&lt;/em&gt; needs to check whether there&amp;#39;s a continuation to jump to, and shuffle the action stack in the way we&amp;#39;re now painfully accustomed to:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; LabelAwaiter Label(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; label)    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Continuation continuation;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; labels.TryGetValue(label, &lt;span class="MethodParameter"&gt;out&lt;/span&gt; continuation);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;new&lt;/span&gt; LabelAwaiter(continuation, &lt;span class="Keyword"&gt;this&lt;/span&gt;);    &lt;br /&gt;}    &lt;br /&gt;    &lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; LabelAwaiter    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Continuation continuation;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Coordinator coordinator;    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt; LabelAwaiter(Continuation continuation, Coordinator coordinator)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.continuation = continuation;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.coordinator = coordinator;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; LabelAwaiter GetAwaiter()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Statement"&gt;return&lt;/span&gt;&amp;#160;&lt;span class="Keyword"&gt;this&lt;/span&gt;;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// If there&amp;#39;s no continuation to execute, just breeze through.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;bool&lt;/span&gt; IsCompleted { get { &lt;span class="Statement"&gt;return&lt;/span&gt; continuation == &lt;span class="Keyword"&gt;null&lt;/span&gt;; } }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; OnCompleted(Action action)    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// We want to execute the ComeFrom continuation, then get back here.&lt;/span&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.stack.Push(action);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; coordinator.stack.Push(continuation.Execute);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt;&amp;#160;&lt;span class="ValueType"&gt;void&lt;/span&gt; GetResult()    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }    &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Almost painfully simple, really.&lt;/p&gt;  &lt;p&gt;So that &lt;em&gt;looks&lt;/em&gt; like all the code that&amp;#39;s used, right? Not &lt;em&gt;quite&lt;/em&gt;...&lt;/p&gt;  &lt;h3&gt;Reusable builders?&lt;/h3&gt;  &lt;p&gt;As we saw in the sample code, we can end up finishing the same async method multiple times (SimpleOtherMethod completes three times). That&amp;#39;s going to call SetResult on the AsyncVoidMethodBuilder three times... which feels like it &lt;em&gt;should&lt;/em&gt; go bang. Indeed, when I revisited my code earlier I wondered why it &lt;em&gt;didn&amp;#39;t&lt;/em&gt; go bang - it&amp;#39;s the sort of illegal state transition the framework is usually pretty good at picking up on.&lt;/p&gt;  &lt;p&gt;Then I remembered - this isn&amp;#39;t the framework&amp;#39;s AsyncVoidMethodBuilder - it&amp;#39;s mine. And my SetResult method in this project does &lt;em&gt;absolutely nothing&lt;/em&gt;. How convenient!&lt;/p&gt;  &lt;h2&gt;Make it stop, make it stop!&lt;/h2&gt;  &lt;p&gt;Okay thiat was a pretty quick tour of some horrible code. You&amp;#39;ll never have to do anything like this with async in sane code, but it certainly made me painfully familiar with how it all worked. Just to recap on the oddities involved:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;We needed to capture a continuation and then immediately keep going, &lt;em&gt;almost&lt;/em&gt; as if the awaiter had said the awaitable had completed already. This involved shenanigans with the execution model and an extra method (Execute)&lt;/li&gt;    &lt;li&gt;We needed to remember the state of a continuation, which we did with reflection.&lt;/li&gt;    &lt;li&gt;We needed to make awaiter.GetResult() a valid call after awaiter had been reset to the default value for the type&lt;/li&gt;    &lt;li&gt;We needed to ensure that the builder created in the skeleton method could have SetResult called on it multiple times&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That&amp;#39;s all on continuations and co-routines, I promise.&lt;/p&gt;  &lt;p&gt;Next time (hopefully soon) I&amp;#39;ll look at an example of how composition works so neatly in async, and then show how we can unit test async methods - at least sometimes.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1802363" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/RPulVO5m5sM" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_+5/default.aspx">C# 5</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Eduasync/default.aspx">Eduasync</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/11/11/eduasync-part-15-implementing-comefrom-with-a-horrible-hack.aspx</feedburner:origLink></item><item><title>Laptop review: Kobalt G150</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/nsJmZkaZ39o/laptop-review-kobalt-g150.aspx</link><pubDate>Sun, 18 Sep 2011 07:09:41 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1799728</guid><dc:creator>skeet</dc:creator><slash:comments>17</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1799728</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1799728</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/09/18/laptop-review-kobalt-g150.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;EDIT, 17th October 2011&lt;/font&gt;&lt;/strong&gt;: Last week Kobalt closed down... so the choice about whether or not I&amp;#39;d buy from them again is now moot. However, &lt;a href="http://pcspecialist.co.uk"&gt;PC Specialist&lt;/a&gt; sells a very similar spec, now including the matte screen...&lt;/p&gt;  &lt;p&gt;As some of you will know, our house was burgled in April, and the thieves took three laptops (and very little else), including my main personal laptop. Obviously I ordered a replacement, partly covered by the insurance from my old laptop. However, I took the opportunity to spoil myself a little... I ordered a G150 from &lt;a href="http://www.kobaltcomputers.co.uk/"&gt;Kobalt Computers&lt;/a&gt;. Various people have taken an interest in the progress and results of this, so this post is a little review.&lt;/p&gt;  &lt;h3&gt;Specs&lt;/h3&gt;  &lt;p&gt;As I said, I spoiled myself a little... the specs are somewhat silly:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Overall, it&amp;#39;s a G150 which is based on the &lt;a href="http://www.clevo.com.tw/en/products/prodinfo.asp?productid=307"&gt;Clevo P150HM&lt;/a&gt; chassis &lt;/li&gt;    &lt;li&gt;Screen: 1920x1080, matte, 95% gamut &lt;/li&gt;    &lt;li&gt;CPU: Intel Sandybridge Core-i7 2720QM; quad core 2.2-3.33GHz &lt;/li&gt;    &lt;li&gt;Graphics: &lt;a href="http://www.notebookcheck.net/NVIDIA-GeForce-GTX-580M.56636.0.html"&gt;Nvidia GeForce GTX 580M&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;RAM: 16GB Corsair DDR3 &lt;/li&gt;    &lt;li&gt;Disk: SSD - Intel 510, 250GB &lt;/li&gt;    &lt;li&gt;Optical: Blu-ray ROM; DVD/RW &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;How does it run?&lt;/h3&gt;  &lt;p&gt;Well how do you &lt;em&gt;think&lt;/em&gt; it runs? :) Obviously it&amp;#39;s very nippy indeed. I&amp;#39;m not sure I&amp;#39;ve ever used more than a couple of cores at a time yet, but it&amp;#39;s nice to know I &lt;em&gt;can&lt;/em&gt; test out parallelization when I want to :) While Windows Experience numbers are obviously pretty crude, they&amp;#39;re pleasant enough that I might as well show them off:&lt;/p&gt;  &lt;p&gt;&lt;img style="margin:5px 5px 5px 0px;" src="http://yoda.arachsys.com/csharp/blogfiles/ExperienceIndex.png" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;Visual Studio 2010 still takes a while to come up (10-15 seconds) whereas Office components start pretty much instantly - so I don&amp;#39;t know where the bottleneck for VS is. You can do an awful lot in terms of both disk and CPU in 10 seconds on this laptop, so it&amp;#39;s a bit of a mystery. (Eclipse starts noticeably faster.) However, once running, Visual Studio is as fast as you&amp;#39;d expect on this machine - builds and tests are nippy, and the editor is noticeably more responsive than on the &amp;quot;make-do&amp;quot; laptop I&amp;#39;ve been using since April.&lt;/p&gt;  &lt;p&gt;I can&amp;#39;t say I&amp;#39;m much of a gamer, but my experiences in Call Of Duty: Black Ops and Portal 2 have been wonderful so far; I can put everything on high settings until it looks absolutely beautiful, and still get a good frame rate. I&amp;#39;ve never had a laptop with a really good graphics card before, and the one in this beast is one of the most powerful out there, so I&amp;#39;ve really got no excuse for &lt;em&gt;not&lt;/em&gt; getting into gaming more, other than my obvious lack of free time. I&amp;#39;m also looking forward to investigating the possibility of writing code in C# to be executed on the GPU - I believe there are a couple of projects around that, so it&amp;#39;ll be fun to look into.&lt;/p&gt;  &lt;p&gt;With a fast SSD, the boot time is fabulously fast - although it &lt;em&gt;does&lt;/em&gt; take a while to go to sleep, as I use hybrid sleep mode and it needs to dump memory to disk first. That&amp;#39;s one downside of having a large amount of memory, of course. There&amp;#39;s still a lot of debate around the longevity of solid state drives, but the improved performance is &lt;em&gt;so&lt;/em&gt; noticeable that I&amp;#39;d definitely not go back to a &amp;quot;normal&amp;quot; hard drive now. I chose the Intel 510 over some slightly faster drives as the 510 is generally reckoned to be more reliable - so I&amp;#39;m hedging my bets somewhat. I suspect the difference in performance between &amp;quot;stupidly fast&amp;quot; and &amp;quot;ridiculously fast&amp;quot; is irrelevant to me.&lt;/p&gt;  &lt;p&gt;The screen is beautiful - just &amp;quot;really nice&amp;quot; for normal desktop work, but &lt;em&gt;amazing&lt;/em&gt; for games and video - that&amp;#39;s where the matte nature really wins out. The contrast is particularly nice, at least in the short tests I&amp;#39;ve performed so far. The hinge feels pleasantly firm but not stiff - it&amp;#39;s hard to judge this early, but hopefully it&amp;#39;ll prove robust over time. This screen is one of the reasons I chose Kobalt - I believe they&amp;#39;re the only UK company selling machines with this screen, and I&amp;#39;d certainly recommend that anyone who has the chance to go for the matte screen should do so.&lt;/p&gt;  &lt;p&gt;Personally I use a separate keyboard most of the time (see below) but the keyboard on the G150 itself is a nice chiclet style one. I&amp;#39;m not terribly fond of the layout of the cursor keys of the fact that there&amp;#39;s no separate home / end / page up / page down keys, but it&amp;#39;s not a big deal. The feeling of the keys themselves is good, and not too loud. The trackpad is fine - I&amp;#39;ve turned off &amp;quot;tap to click&amp;quot; as it always ends up activating when I don&amp;#39;t want to, but that&amp;#39;s not specific to this particular laptop - I &lt;em&gt;always&lt;/em&gt; find the same thing. Maybe I type with my palms particularly close to the trackpad, or something like that.&lt;/p&gt;  &lt;p&gt;A few more random, esoteric points:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The power socket is &amp;quot;grippy&amp;quot; which makes it slightly harder to pull out the power, but does give a feeling of security. This is clearly a deliberate decision, and while it&amp;#39;s not one which would suit &lt;em&gt;everyone&lt;/em&gt;, I&amp;#39;m pretty happy with it. &lt;/li&gt;    &lt;li&gt;The fan comes on and goes off reasonably regularly, which can prove a little distracting sometimes, but is the natural result of having a fast/hot laptop, I guess. The fan itself is fairly quiet under normal load, so I&amp;#39;d probably be fine with it being &lt;em&gt;constantly&lt;/em&gt; on - it&amp;#39;s the stop / start nature that jars a little. Not a big deal once you get used to it. &lt;/li&gt;    &lt;li&gt;The webcam is really washed out - I don&amp;#39;t think I&amp;#39;d really want to use it, to be honest. I don&amp;#39;t know whether it&amp;#39;s my particular hardware, the general make/model, or the settings (which I&amp;#39;ve played with and improved &lt;em&gt;somewhat&lt;/em&gt;, but not to really acceptable levels) &lt;/li&gt;    &lt;li&gt;The built-in microphone is located on the keyboard, which is a little bizarre and obviously not helpful for any time you&amp;#39;d be typing as well as talking. There&amp;#39;s a lot of white noise with it compared with actual signal - I couldn&amp;#39;t get a Skype test call to be audible without it also having huge amounts of hiss. Fortunately, this isn&amp;#39;t a problem for me - I have a standalone microphone which I use for screencasts etc. That&amp;#39;s previously been problematically quiet with other laptops, possibly due to drawing a lot of power - but it works perfectly with this laptop. I&amp;#39;m also getting a Corsair headset, which should be handy both for gaming and podcast recordings. &lt;/li&gt;    &lt;li&gt;The machine itself is fairly bulky, and the power brick is huge - but the feeling of the chassis is a very attractive matte black. If you&amp;#39;re looking for a sleek laptop to carry around a lot, this probably wouldn&amp;#39;t be the best choice, but most of the time I keep my laptop on the same table at home. I went for a 15&amp;quot; rather than 17&amp;quot; as it makes a big difference when carrying it around to conferences, but the extra thickness required to house and cool the powerful components doesn&amp;#39;t really bother me. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Overall, I&amp;#39;m really pleased with the laptop. As far as I can tell so far, the build quality is excellent - no problems at all. The poor quality of the microphone and webcam are a niggly disappointment, but not one that bothers me enough to find out whether they&amp;#39;re &amp;quot;working as expected&amp;quot; or not.&lt;/p&gt;  &lt;h3&gt;The buying experience&lt;/h3&gt;  &lt;p&gt;This is where some of you may be relishing the prospect of reading a rant against Kobalt - but I&amp;#39;m not going to air lots of dirty laundry here. It &lt;em&gt;did&lt;/em&gt; take a very long time for the laptop to arrive - over three months - but the causes of this were varied, and are worth mentioning at least in passing. I&amp;#39;m hoping that a summary of frustrations and the good parts will give the right impression without getting ugly.&lt;/p&gt;  &lt;p&gt;My first cause of frustration occurred very early - before I&amp;#39;d even received a detailed order confirmation from Kobalt. They&amp;#39;d suffered from a high proportion of staff going down with norovirus around the time I ordered. This is the sort of thing which will obviously hit a small company like Kobalt rather more than bigger ones, but it wasn&amp;#39;t a great start; for a week all I had was an email saying that I&amp;#39;d paid Kobalt for &lt;em&gt;something&lt;/em&gt;, but I couldn&amp;#39;t even check whether the details were right.&lt;/p&gt;  &lt;p&gt;Some of the delays actually put Kobalt into a &lt;em&gt;better&lt;/em&gt; light as far as I&amp;#39;m concerned. In particular, I&amp;#39;d originally ordered an AMD 6970 graphics card and a Vertex 3 SSD. Kobalt withdrew both of these components from sale: the 6970 was failing too often in testing, and the Vertex 3 was causing blue screens, sometimes in testing and occasionally on customer machines, due to an issue between the laptop chipset and the disk. Some other vendors would no doubt have kept selling these components and let the customer take the risk of losing the use of the laptop while it went back for repair, and I applaud Kobalt for &lt;em&gt;not&lt;/em&gt; doing this.&lt;/p&gt;  &lt;p&gt;Likewise my order was actually built twice: the first one failed testing - the motherboard failed, so had to be built from scratch. Again, I&amp;#39;m very happy about this - I&amp;#39;d obviously rather have a delay but get a working laptop in the end than get a defective one sooner. This also worked to my advantage in terms of the graphics card; although I&amp;#39;d only ordered a 485M, the first one was used in another customer&amp;#39;s machine while waiting for a new motherboard for me... by which time the 485M was no longer readily available. Kobalt swapped in the 580M for no extra charge.&lt;/p&gt;  &lt;p&gt;Other delays were only partially under Kobalt&amp;#39;s control - for example, their order management system blew up in August. Can you blame a company for their internal systems failing? It&amp;#39;s hard to say - and I&amp;#39;ll be the first to admit I don&amp;#39;t have the details. Was it due to cutting corners by getting a cheap ordering system which might be expected to be flaky? Was it due to something catastrophic which would only happen once in a million years? Should there have been better &amp;quot;emergency backup&amp;quot; procedures? I don&amp;#39;t know - but it &lt;em&gt;feels&lt;/em&gt; like something that customers shouldn&amp;#39;t be exposed to.&lt;/p&gt;  &lt;p&gt;One benefit of the delays was that I was able to change my order a couple of times - upping the CPU and memory, choosing a different graphics card and disk drive etc. Kobalt have been very flexible around this; it was considerably easier to change the configuration than I suspect it would have been with somewhere like Dell.&lt;/p&gt;  &lt;p&gt;My main issue through all of this was communication - which wasn&amp;#39;t all bad, but was definitely flaky. I suspect Kobalt would argue that I had unreasonable expectations, whereas I&amp;#39;d say it&amp;#39;s just part of providing good customer service. The problems that Kobalt experienced obviously made all of this &lt;em&gt;much&lt;/em&gt; worse than normal, but I still think there&amp;#39;s a mismatched set of expectations there. I clearly wasn&amp;#39;t the only one getting frustrated - the forums had a lot of posts complaining of a lack of updates - but equally, satisfied customers don&amp;#39;t tend to post much to provide balance. It&amp;#39;s very obvious on the forums that while people &lt;em&gt;have&lt;/em&gt; been frustrated with the buying process, almost everyone&amp;#39;s really happy with the machine they get in the end, and Kobalt are actually really good at answering questions about drivers etc afterwards.&lt;/p&gt;  &lt;p&gt;My own experience of communicating with Kobalt was negative until the reasonably late stages of the order, but I was then phoned to be informed of the laptop coming out of testing and again to check shipping dates, which was good. (In this case it was particularly important as without the check, the laptop would have been delivered to the office on Saturday, where there may well not have been anyone prepared to sign for it.)&lt;/p&gt;  &lt;p&gt;For a week or so after I received my laptop I still saw quite a few frustrated posts from other customers, but now that &lt;em&gt;seems&lt;/em&gt; to have gone down significantly. It&amp;#39;s possible that I&amp;#39;m just not seeing the other complaining posts (as such posts are often deleted - leading to the customer in question getting &lt;em&gt;more&lt;/em&gt; frustrated, of course). I&amp;#39;m currently hopeful that I happen to have just ordered at a really bad time where Kobalt was suffering a series of unrelated problems. Whether they handled those as well as they could have done is up for debate, but &lt;em&gt;hopefully&lt;/em&gt; new customers wouldn&amp;#39;t see the same problems.&lt;/p&gt;  &lt;p&gt;It should be noted that Kobalt is definitely trying to get better, too. In August they introduced a new &lt;a href="http://www.kobaltcomputers.co.uk/forum/showthread.php?3918-New!!-Kobalt-Customer-Promise"&gt;Customer Promise&lt;/a&gt; around price, upgrades, and delivery times. In particular, if your order takes more than 6 weeks, you can choose between various games and accessories as a gift. (I chose two games from Steam.) Also, they&amp;#39;re actively recruiting, so hopefully that will help on the communications front, too.&lt;/p&gt;  &lt;h3&gt;Accessories&lt;/h3&gt;  &lt;p&gt;As tends to happen while waiting for something, I got itchy and started buying accessories to go with the new laptop. I thought I might as well mention those at the same time...&lt;/p&gt;  &lt;p&gt;External USB 3 drive: &lt;a href="http://www.amazon.co.uk/dp/B002NEFU9M"&gt;Western Digital MyPassport&lt;/a&gt;. I would probably have bought a eSata drive if I&amp;#39;d found one with as neat a form factor as this, but there just don&amp;#39;t seem to be many eSata drives around yet. Hopefully this will change, as I &lt;em&gt;do&lt;/em&gt; notice my USB mouse/keyboard responding sluggishly while I&amp;#39;m putting a lot of traffic through the drive - but apart from that, it&amp;#39;s lovely. It&amp;#39;s a really nice form factor, and seems to take advantage of the USB 3 ports on my laptop to deliver pretty reasonable performance. I&amp;#39;m expecting this to be used primarily for VMs - I&amp;#39;ve heard mixed reports of using VMs with SSDs, including the possibility that the two really don&amp;#39;t play nicely, leading to early drive failure. I don&amp;#39;t know whether this is accurate or not, but I&amp;#39;m being cautious. Overall, I&amp;#39;m pretty happy with this, although it&amp;#39;s reasonably hard to get excited about a disk drive...&lt;/p&gt;  &lt;p&gt;Keyboard: I do quite a bit of typing, and while I&amp;#39;m used to laptop keyboards, they&amp;#39;re obviously somewhat constrained. I had previously been using a &lt;a href="http://www.logitech.com/en-gb/keyboards/keyboard/devices/6007"&gt;Logitech K340&lt;/a&gt; which is nice, but I treated myself to a &lt;a href="http://www.logitech.com/en-gb/keyboards/keyboard/devices/7288"&gt;K800&lt;/a&gt; for the new machine. Both of these use Logitech&amp;#39;s &amp;quot;Unifying&amp;quot; receiver, which is &lt;em&gt;wonderful&lt;/em&gt; - it&amp;#39;s a tiny little receiver which I just leave permanently in the USB port. It works with quite a few Logitech peripherals, so I share the same receiver for my keyboard and the &lt;a href="http://www.logitech.com/en-gb/mice-pointers/mice/devices/5846"&gt;Anywhere MX&lt;/a&gt; mouse I use. The K800 keyboard is really nice - a lovely action, a sensible layout of Ins/Del/Home/End/PgUp/PgDn (which is its main benefit over the K340, to be honest) and it&amp;#39;s rechargable via USB. The backlighting is a nice extra, although it&amp;#39;s probably not going to actually be &lt;em&gt;useful&lt;/em&gt; for me. It&amp;#39;s fun to just wave your hand over it and watch it light up though... I&amp;#39;m easily pleased :)&lt;/p&gt;  &lt;p&gt;I also bought a &lt;a href="http://www.amazon.co.uk/dp/B005626UPG"&gt;Belkin Screencast WiDi 2.0&lt;/a&gt;, which turns out to have been a mistake. I had &lt;em&gt;thought&lt;/em&gt; that because I was using a Sandybridge laptop with an appropriate Intel wifi card, I&amp;#39;d be able to use WiDi - a technology which allows you to transmit video and sound to a receiver which can then plug into the TV. Yay, I can display Youtube etc on the TV without leaving the comfort of the sofa, right? Not so much - it turns out that this &lt;em&gt;only&lt;/em&gt; works if you&amp;#39;re also using the integrated graphics card; as I&amp;#39;m using a separate GPU, it&amp;#39;s a no-go. This wasn&amp;#39;t made as obvious as it might be on Intel&amp;#39;s web site about WiDi - it&amp;#39;s there if you dig, but it&amp;#39;s not obvious. Just to be clear, this is in &lt;em&gt;no&lt;/em&gt; way Kobalt&amp;#39;s fault - they never claimed the new laptop would be WiDi compatible. I&amp;#39;ve now sent the Screencast (which was no use to me for anything else) to Kobalt so they can try it out with other laptops. (I suspect the GS150 may work with it, for example.)&lt;/p&gt;  &lt;h3&gt;VM experiment&lt;/h3&gt;  &lt;p&gt;As I&amp;#39;ve tweeted before, I did have one hope for actually using most of the 16GB of memory. I don&amp;#39;t want to run VMs directly from the SSD, as I mentioned before - but I had a thought of having the virtual disk &lt;em&gt;on&lt;/em&gt; the SSD, but then mounting it as a ram drive. That way I&amp;#39;d only need to write to the disk after shutting down the VM - one big write instead of frequent spraying access.&lt;/p&gt;  &lt;p&gt;That would only work with a small drive, of course... but I &lt;em&gt;hoped&lt;/em&gt; I&amp;#39;d just about be able to get Windows 7 Home Premium + Visual Studio into a small enough drive. With 1GB of memory for the VM and 2GB of memory for the host machine I can have a 13GB ram drive - and I can install Windows 7 on that using Virtual PC, but Virtual PC also uses disk space alongside the VHD for memory for the VM, which obviously takes another 1GB off the usable size. I &lt;em&gt;nearly&lt;/em&gt; managed it, but not quite. I may give it another go with Virtual Box and the Express edition of VS11... I&amp;#39;ll blog again if I get it working, but I didn&amp;#39;t want to hold up this post forever...&lt;/p&gt;  &lt;p&gt;In terms of getting &lt;em&gt;anything&lt;/em&gt; working, it took a little while - DataRam&amp;#39;s &lt;a href="http://memory.dataram.com/products-and-services/software/ramdisk"&gt;RAMDisk product&lt;/a&gt; kept hanging while closing down; &lt;a href="http://www.ltr-data.se/opencode.html/#ImDisk"&gt;imdisk&lt;/a&gt; gave me access problems even after trying all the suggested tweaks, but &lt;a href="http://www.romexsoftware.com/en-us/index.html"&gt;VSuite Ramdisk (server edition)&lt;/a&gt; seems to do the job. It&amp;#39;s not hugely cheap (and I need the server edition to support a drive over 4GB) but &lt;em&gt;if&lt;/em&gt; I can get everything working, I may go with it. Currently I&amp;#39;m using the trial edition.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;I guess the obvious question to ask is &amp;quot;If I had my time again, would I take the same action?&amp;quot;&lt;/p&gt;  &lt;p&gt;Well, it&amp;#39;s obviously been a frustrating experience, but the results should keep me happy for a long time. I think I would be &lt;em&gt;cautious&lt;/em&gt; about buying from Kobalt again, but probably less so than you might expect. I&amp;#39;d probably hang out in the forums for a while to see whether folks were generally happy at the time. I&amp;#39;m &lt;em&gt;hoping&lt;/em&gt; I was just unlucky, and hit a particularly nasty time in Kobalt&amp;#39;s history - I can&amp;#39;t imagine the staff there have enjoyed those three months any more than I did - and that normally everything runs smoothly. If I were in a real hurry I&amp;#39;d probably go for an off-the-shelf solution, but that&amp;#39;s a different matter - when you buy a custom machine you should &lt;em&gt;expect&lt;/em&gt; it to take a bit longer. Just not three months, normally :)&lt;/p&gt;  &lt;p&gt;I&amp;#39;d certainly be happy to buy from Kobalt again in terms of the quality of the product - it&amp;#39;s a &lt;em&gt;lovely&lt;/em&gt; laptop, and I&amp;#39;m delighted with its performance, display and general handling. Obviously I regret buying the Screencast, but all my other decisions - memory, disk, external keyboard etc - have turned out well so far.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1799728" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/nsJmZkaZ39o" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/General/default.aspx">General</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/09/18/laptop-review-kobalt-g150.aspx</feedburner:origLink></item><item><title>Upcoming speaking engagements</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/ZKs8HsqQYw4/upcoming-speaking-engagements.aspx</link><pubDate>Fri, 02 Sep 2011 16:53:17 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1798771</guid><dc:creator>skeet</dc:creator><slash:comments>8</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1798771</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1798771</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/09/02/upcoming-speaking-engagements.aspx#comments</comments><description>&lt;p&gt;It&amp;#39;s just occurred to me that I&amp;#39;ve forgotten to mention a few of the things I&amp;#39;ll be up to in the near-ish future. (I&amp;#39;ve &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/07/28/speaking-engagement-progressive-net-london-september-7th.aspx"&gt;talked about next week&amp;#39;s Progressive .NET session before&lt;/a&gt;.) This is just a quick rundown - follow the links for more blurb and details.&lt;/p&gt;  &lt;h2&gt;.NET Developer Network - Bristol, September 21st (evening)&lt;/h2&gt;  &lt;p&gt;I&amp;#39;ll be &lt;a href="http://dotnetdevnet.com/Meetings/tabid/54/EntryID/58/Default.aspx"&gt;talking about async&lt;/a&gt; in Bristol - possibly at a high level, possibly in detail, depending on the audience experience. This is my first time talking with this particular user group, although I&amp;#39;m sure there&amp;#39;ll be some familiar faces. Come along if you&amp;#39;re in the area.&lt;/p&gt;  &lt;h2&gt;Øredev 2011 - Malmö, November 9th&lt;/h2&gt;  &lt;p&gt;It&amp;#39;s a whistle-stop trip to Sweden as I&amp;#39;m running out of vacation days; I&amp;#39;m flying out on the Tuesday evening and back on the Wednesday evening, but while I&amp;#39;m there I&amp;#39;ll give two talks:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://oredev.org/2011/sessions/async-101"&gt;Async 101&lt;/a&gt; (yes, &lt;em&gt;more&lt;/em&gt; async; I wonder at what point I&amp;#39;ll have given as many talks about it as Mads) &lt;/li&gt;    &lt;li&gt;&lt;a href="http://oredev.org/2011/sessions/a-less-technical-talk-on-technical-communication"&gt;Effective technical communication&lt;/a&gt; (not a particularly technical talk, but definitely specific to &lt;em&gt;technical&lt;/em&gt; communication) &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Last year I had an absolute blast - looking forward to this year, even though I won&amp;#39;t have as much time for socializing.&lt;/p&gt;  &lt;h2&gt;Stack Overflow Dev Days 2011 - London, November 14th - cancelled!&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;Update: &lt;a href="http://blog.stackoverflow.com/2011/09/devdays-2011-is-cancelled/"&gt;Dev Days has been cancelled&lt;/a&gt;. I&amp;#39;m still hoping to do &lt;em&gt;something&lt;/em&gt; around this topic, and there may be small-scale meet-ups in London anyway.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Two years ago I talked about &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2009/11/02/omg-ponies-aka-humanity-epic-fail.aspx"&gt;how humanity had let the world of software engineering down&lt;/a&gt;. This was one of the best talks I&amp;#39;ve ever given, and introduced the world to Tony the Pony. Unfortunately that puts the bar relatively high for this year&amp;#39;s talk - at least, high by my own pretty low standards.&lt;/p&gt;  &lt;p&gt;In a somewhat odd topic for a &lt;a href="http://pobox.com/~skeet/preaching"&gt;Christian&lt;/a&gt; and a happy employee of a company with a &lt;a href="http://investor.google.com/corporate/code-of-conduct.html"&gt;code of conduct&lt;/a&gt; which starts &amp;quot;Don&amp;#39;t be evil,&amp;quot; this year&amp;#39;s talk is entitled &lt;a href="http://devdays.stackoverflow.com/sessions/thinking-in-evil/"&gt;&amp;quot;Thinking in evil.&amp;quot;&lt;/a&gt; As regular readers are no doubt aware, I love torturing the C# language and forcing the compiler to work with code which would make any right-thinking software engineer cringe. I was particularly gratified recently when Eric Lippert commented on &lt;a href="http://stackoverflow.com/questions/7113347/c-assignment-in-an-if-statement/7113387#7113387"&gt;one of my Stack Overflow answers&lt;/a&gt; that this was &amp;quot;the best abuse of C# I&amp;#39;ve seen in a while.&amp;quot; I&amp;#39;m looking forward to talking about why I think it&amp;#39;s genuinely a good idea to think about nasty code like this - not to &lt;em&gt;use&lt;/em&gt; it, but to get to know your language of choice more intimately. Like last time, I have little idea of &lt;em&gt;exactly&lt;/em&gt; what this talk will be like, but I&amp;#39;m really looking forward to it.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1798771" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/ZKs8HsqQYw4" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Speaking+engagements/default.aspx">Speaking engagements</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Stack+Overflow/default.aspx">Stack Overflow</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Evil+Code/default.aspx">Evil Code</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/09/02/upcoming-speaking-engagements.aspx</feedburner:origLink></item><item><title>Optimization and generics, part 2: lambda expressions and reference types</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/cXsL5tTiNHw/optimization-and-generics-part-2-lambda-expressions-and-reference-types.aspx</link><pubDate>Mon, 22 Aug 2011 23:06:18 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1798036</guid><dc:creator>skeet</dc:creator><slash:comments>17</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1798036</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1798036</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/08/23/optimization-and-generics-part-2-lambda-expressions-and-reference-types.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;As with almost any performance work, your mileage may vary (in particular the 64-bit JIT may work differently) and you almost certainly shouldn&amp;#39;t care. Relatively few people write production code which is worth micro-optimizing. Please don&amp;#39;t take this post as an invitation to make code more complicated for the sake of irrelevant and possibly mythical performance changes.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;It took me a surprisingly long time to find the problem described in the &lt;a href="http://msmvps.com/blogs/jon_skeet/archive/2011/08/22/optimization-and-generics-part-1-the-new-constraint.aspx"&gt;previous blog post&lt;/a&gt;, and almost no time at all to fix it. I understood why it was happening. This next problem took a while to identify at all, but even when I&amp;#39;d found a workaround I had no idea why it worked. Furthermore, I couldn&amp;#39;t reproduce it in a test case... because I was looking for the wrong set of triggers. I&amp;#39;ve now found at least &lt;em&gt;some&lt;/em&gt; of the problem though.&lt;/p&gt;  &lt;p&gt;This time the situation in Noda Time is harder to describe, although it concerns the same area of code. In various places I need to create new delegates containing parsing steps and add them to the list of steps required for a full parse. I can always use lambda expressions, but in many cases I&amp;#39;ve got the same logic repeatedly... so I decided to pull it out into a method. Bang - suddenly the code runs far slower. (In reality, I&amp;#39;d performed this refactoring first, and &amp;quot;unrefactored&amp;quot; it to speed things up.)&lt;/p&gt;  &lt;p&gt;I &lt;em&gt;think&lt;/em&gt; the problem comes down to method group conversions with generic methods and a type argument which is a reference type. The CLR isn&amp;#39;t very good at them, and the C# compiler uses them more than it needs to.&lt;/p&gt;  &lt;h3&gt;Show me the benchmark!&lt;/h3&gt;  &lt;p&gt;The &lt;a href="http://pobox.com/~skeet/csharp/blogfiles/GenericsAndLambdas.cs"&gt;complete benchmark code&lt;/a&gt; is available of course, but fundamentally I&amp;#39;m doing the same thing in each test case: creating a delegate of type Action which does nothing, and then checking that the delegate reference is non-null (just to avoid the JIT optimizing it away). In each case this is done in a generic method with a single type parameter. I call each method in two ways: once with int as the type argument, and once with string as the type argument. Here are the different cases involved:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Use a lambda expression: &lt;font face="Courier New"&gt;&lt;strong&gt;Action foo = () =&amp;gt; {};&lt;/strong&gt;&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;Fake what I &lt;em&gt;expected&lt;/em&gt; the compiler to do: keep a separate generic cache class with a static variable for the delegate; populate the cache once if necessary, and thereafter use the cache field &lt;/li&gt;    &lt;li&gt;Fake what the compiler is &lt;em&gt;actually&lt;/em&gt; doing with the lambda expression: write a separate generic method and perform a method group conversion to it &lt;/li&gt;    &lt;li&gt;Do what the compiler &lt;em&gt;could&lt;/em&gt; do: write a separate non-generic method and perform a method group conversion to it &lt;/li&gt;    &lt;li&gt;Use a method group conversion to a static (non-generic) method on a generic type &lt;/li&gt;    &lt;li&gt;Use a method group conversion to an instance (non-generic) method on a generic type, via a generic cache class with a single field in referring to an instance of the generic class &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;(Yes, the last one is a bit convoluted - but the line in the method itself is simple: &lt;font face="Courier New"&gt;&lt;strong&gt;Action foo = ClassHolder&amp;lt;T&amp;gt;.SampleInstance.NoOpInstance;&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Remember, we&amp;#39;re doing &lt;em&gt;each&lt;/em&gt; of these in a generic method, and calling that generic method using a type argument of either int or string. (I&amp;#39;ve run a few tests, and the exact type isn&amp;#39;t important - all that matters is that int is a value type, and string is a reference type.)&lt;/p&gt;  &lt;p&gt;Importantly, we&amp;#39;re &lt;em&gt;not&lt;/em&gt; capturing any variables, and the type parameter is &lt;em&gt;not&lt;/em&gt; involved in either the delegate type or any part of the implementation body.&lt;/p&gt;  &lt;h3&gt;Benchmark results&lt;/h3&gt;  &lt;p&gt;Again, times are in milliseconds - but this time I didn&amp;#39;t want to run it for 100 million iterations, as the &amp;quot;slow&amp;quot; versions would have taken far too long. I&amp;#39;ve run this on the x64 JIT as well and seen the same effect, but I haven&amp;#39;t included the figures here.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Times in milliseconds for 10 million iterations&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td&gt;&lt;strong&gt;Test&lt;/strong&gt;&lt;/td&gt;        &lt;td align="right"&gt;&lt;strong&gt;TestCase&amp;lt;int&amp;gt;&lt;/strong&gt;&lt;/td&gt;        &lt;td align="right"&gt;&lt;strong&gt;TestCase&amp;lt;string&amp;gt;&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Lambda expression&lt;/td&gt;        &lt;td align="right"&gt;180&lt;/td&gt;        &lt;td align="right"&gt;29684&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Generic cache class&lt;/td&gt;        &lt;td align="right"&gt;90&lt;/td&gt;        &lt;td align="right"&gt;288&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Generic method group conversion&lt;/td&gt;        &lt;td align="right"&gt;184&lt;/td&gt;        &lt;td align="right"&gt;30017&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Non-generic method group conversion&lt;/td&gt;        &lt;td align="right"&gt;178&lt;/td&gt;        &lt;td align="right"&gt;189&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Static method on generic type&lt;/td&gt;        &lt;td align="right"&gt;180&lt;/td&gt;        &lt;td align="right"&gt;29276&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;Instance method on generic type&lt;/td&gt;        &lt;td align="right"&gt;202&lt;/td&gt;        &lt;td align="right"&gt;299&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;Yes, it&amp;#39;s about &lt;em&gt;150 times&lt;/em&gt; slower to create a delegate from a generic method with a reference type as the type argument than with a value type... and yet this is the first I&amp;#39;ve heard of this. (I wouldn&amp;#39;t be surprised if there were a post from the CLR team about it somewhere, but I don&amp;#39;t think it&amp;#39;s common knowledge by any means.)&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;One of the tricky things is that it&amp;#39;s hard to know exactly what the C# compiler is going to do with any given lambda expression. In fact, the method which was causing me grief earlier on &lt;em&gt;isn&amp;#39;t&lt;/em&gt; generic, but it&amp;#39;s in a generic type and captures some variables which use the type parameters - so perhaps that&amp;#39;s causing a generic method group conversion somewhere along the way.&lt;/p&gt;  &lt;p&gt;Noda Time is a relatively extreme case, but if you&amp;#39;re using delegates in any performance-critical spots, you should really be aware of this issue. I&amp;#39;m going to ping Microsoft (first informally, and then via a Connect report if that would be deemed useful) to see if there&amp;#39;s an awareness of this internally as potential &amp;quot;gotcha&amp;quot;, and whether there&amp;#39;s anything that can be done. Normal trade-offs of work required vs benefit apply, of course. It&amp;#39;s possible that this really is an edge case... but with lambdas flying everywhere these days, I&amp;#39;m not sure that it is.&lt;/p&gt;  &lt;p&gt;Maybe tomorrow I&amp;#39;ll actually be able to finish getting Noda Time moved onto the new system... all of this performance work has been a fun if surprising distraction from the main job of shipping working code...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1798036" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/cXsL5tTiNHw" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Benchmarking/default.aspx">Benchmarking</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/08/23/optimization-and-generics-part-2-lambda-expressions-and-reference-types.aspx</feedburner:origLink></item><item><title>Optimization and generics, part 1: the new() constraint (updated: now with CLR v2 results)</title><link>http://feedproxy.google.com/~r/JonSkeetCodingBlog/~3/9OK-4m3wBiU/optimization-and-generics-part-1-the-new-constraint.aspx</link><pubDate>Mon, 22 Aug 2011 21:57:55 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1798032</guid><dc:creator>skeet</dc:creator><slash:comments>14</slash:comments><wfw:commentRss>http://msmvps.com/blogs/jon_skeet/rsscomments.aspx?PostID=1798032</wfw:commentRss><wfw:comment>http://msmvps.com/blogs/jon_skeet/commentapi.aspx?PostID=1798032</wfw:comment><comments>http://msmvps.com/blogs/jon_skeet/archive/2011/08/22/optimization-and-generics-part-1-the-new-constraint.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;As with almost any performance work, your mileage may vary (in particular the 64-bit JIT may work differently) and you almost certainly shouldn&amp;#39;t care. Relatively few people write production code which is worth micro-optimizing. Please don&amp;#39;t take this post as an invitation to make code more complicated for the sake of irrelevant and possibly mythical performance changes.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;I&amp;#39;ve been doing quite a bit of work on Noda Time recently - and have started getting my head round all the work that James Keesey has put into the parsing/formatting. I&amp;#39;ve been reworking it so that we can do everything without throwing any exceptions, and also to work on the idea of parsing a pattern once and building a sequence of actions for both formatting and parsing from the action. To format or parse a value, we then just need to apply the actions in turn. &lt;a href="http://www.comparethemeerkat.com/"&gt;Simples&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Given that this is all in the name of performance (and &lt;a href="http://noda-time.blogspot.com/2010/02/performance-matters.html"&gt;I consider Noda Time to be worth optimizing pretty hard&lt;/a&gt;) I was pretty cross when I ran a complete revamp through the little benchmarking tool we use, and found that my rework had made everything &lt;em&gt;much&lt;/em&gt; slower. Even parsing a value &lt;em&gt;after parsing the pattern&lt;/em&gt; was slower than parsing both the value and the pattern together. Something was clearly very wrong.&lt;/p&gt;  &lt;p&gt;In fact, it turns out that at least two things were very wrong. The first (the subject of this post) was easy to fix and actually made the code a little more flexible. The second (the subject of the next post, which may be tomorrow) is going to be harder to work around.&lt;/p&gt;  &lt;h3&gt;The new() constraint&lt;/h3&gt;  &lt;p&gt;In my SteppedPattern type, I have a generic type parameter - TBucket. It&amp;#39;s already constrained in terms of another type parameter, but that&amp;#39;s irrelevant as far as I&amp;#39;m aware. (After today though, I&amp;#39;m taking very little for granted...) The important thing is that before I try to parse a &lt;em&gt;value&lt;/em&gt;, I want to create a new bucket. The idea is that bits of information end up in the bucket as they&amp;#39;re being parsed, and at the very end we put everything together. So each parse operation requires a new bucket. How can we create one in a nice generic way?&lt;/p&gt;  &lt;p&gt;Well, we can just call its public parameterless constructor. I don&amp;#39;t mind the types involved having such a constructor, so all we need to do is add the new() constraint, and then we can call new TBucket():&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Somewhat simplified...&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; SteppedPattern&amp;lt;TResult, TBucket&amp;gt; : IParsePattern&amp;lt;TResult&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Linq"&gt;where&lt;/span&gt; TBucket : &lt;span class="Keyword"&gt;new&lt;/span&gt;()     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; ParseResult&amp;lt;TResult&amp;gt; Parse(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; value)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TBucket bucket = &lt;span class="Keyword"&gt;new&lt;/span&gt; TBucket();     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Rest of parsing goes here&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Great! Nice and simple. Unfortunately, it turned out that that one line of code was taking 75% of the time to parse a value. Just creating an empty bucket - pretty much the simplest bit of parsing. I was amazed when I discovered that.&lt;/p&gt;  &lt;h3&gt;Fixing it with a provider&lt;/h3&gt;  &lt;p&gt;The fix is reasonably easy. We just need to tell the type how to create an instance, and we can do that with a delegate:&lt;/p&gt;  &lt;div class="code"&gt;&lt;span class="InlineComment"&gt;// Somewhat simplified...&lt;/span&gt;     &lt;br /&gt;&lt;span class="Modifier"&gt;internal&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;sealed&lt;/span&gt;&amp;#160;&lt;span class="ReferenceType"&gt;class&lt;/span&gt; SteppedPattern&amp;lt;TResult, TBucket&amp;gt; : IParsePattern&amp;lt;TResult&amp;gt;     &lt;br /&gt;{     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;private&lt;/span&gt;&amp;#160;&lt;span class="Modifier"&gt;readonly&lt;/span&gt; Func&amp;lt;TBucket&amp;gt; bucketProvider;     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;internal&lt;/span&gt; SteppedPattern(Func&amp;lt;TBucket&amp;gt; bucketProvider)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Keyword"&gt;this&lt;/span&gt;.bucketProvider = bucketProvider;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span class="Modifier"&gt;public&lt;/span&gt; ParseResult&amp;lt;TResult&amp;gt; Parse(&lt;span class="ReferenceType"&gt;string&lt;/span&gt; value)     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; TBucket bucket = bucketProvider();     &lt;br /&gt;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span class="InlineComment"&gt;// Rest of parsing goes here&lt;/span&gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }     &lt;br /&gt;} &lt;/div&gt;  &lt;p&gt;Now I can just call new SteppedPattern(() =&amp;gt; new OffsetBucket()) or whatever. This also means I can keep the constructor internal, not that I care much. I could even reuse old parse buckets if that wouldn&amp;#39;t be a semantic problem - in other cases it could be useful. Hooray for lambda expressions - until we get to the next post, anyway.&lt;/p&gt;  &lt;h3&gt;Show me the figures!&lt;/h3&gt;  &lt;p&gt;You don&amp;#39;t want to have to run Noda Time&amp;#39;s benchmarks to see the results for yourself, so I wrote a small benchmark to time &lt;em&gt;just&lt;/em&gt; the construction of a generic type. As a measure of how insignificant this would be for most apps, these figures are in milliseconds, performing 100 &lt;em&gt;million&lt;/em&gt; iterations of the action in question. Unless you&amp;#39;re going to do this in performance-critical code, you just shouldn&amp;#39;t care.&lt;/p&gt;  &lt;p&gt;Anyway, the benchmark has four custom types: two classes, and two structs - a small and a large version of each. The small version has a single int field; the large version has eight long fields. For each type, I benchmarked both approaches to initialization.&lt;/p&gt;  &lt;p&gt;The results on two machines (32-bit and 64-bit) are below, for both the v2 CLR and v4. The 64-bit machine is much faster in general - you should only compare results within one machine, as it were.)&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;CLR v4: 32-bit results (ms per 100 million iterations)&lt;/strong&gt;&lt;/h3&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Test type&lt;/td&gt;        &lt;td valign="top" width="133"&gt;new() constraint&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Provider delegate&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;689&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1225&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;11188&lt;/td&gt;        &lt;td valign="top" width="133"&gt;7273&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;16307&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1690&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;17471&lt;/td&gt;        &lt;td valign="top" width="133"&gt;3017&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;CLR v4: 64-bit results (ms per 100 million iterations)&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="401"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Test type&lt;/td&gt;        &lt;td valign="top" width="133"&gt;new() constraint&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Provider delegate&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;473&lt;/td&gt;        &lt;td valign="top" width="133"&gt;868&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;2670&lt;/td&gt;        &lt;td valign="top" width="133"&gt;2396&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;8366&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1189&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;8805&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1529&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;h3&gt;&lt;strong&gt;CLR v2: 32-bit results (ms per 100 million iterations)&lt;/strong&gt;&lt;/h3&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="400"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Test type&lt;/td&gt;        &lt;td valign="top" width="133"&gt;new() constraint&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Provider delegate&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;703&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1246&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;11411&lt;/td&gt;        &lt;td valign="top" width="133"&gt;7392&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;143967&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1791&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;143107&lt;/td&gt;        &lt;td valign="top" width="133"&gt;2581&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;CLR v2: 64-bit results (ms per 100 million iterations)&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="401"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Test type&lt;/td&gt;        &lt;td valign="top" width="133"&gt;new() constraint&lt;/td&gt;        &lt;td valign="top" width="133"&gt;Provider delegate&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;510&lt;/td&gt;        &lt;td valign="top" width="133"&gt;686&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large struct&lt;/td&gt;        &lt;td valign="top" width="133"&gt;2334&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1731&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Small class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;81801&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1539&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="133"&gt;Large class&lt;/td&gt;        &lt;td valign="top" width="133"&gt;83293&lt;/td&gt;        &lt;td valign="top" width="133"&gt;1896&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;(An earlier version of this post had a mistake - my original tests used structs for everything, despite the names.)&lt;/p&gt;  &lt;p&gt;Others have reported slightly different results, including the new() constraint being better for both large &lt;em&gt;and&lt;/em&gt; small structs.&lt;/p&gt;  &lt;p&gt;Just in case you hadn&amp;#39;t spotted them, look at the results for classes. Those are the real results - it took over 2 minutes to run the test using the new() constraint on my 32-bit laptop, compared with under two seconds for the provider. Yikes. This was actually the situation I was in for Noda Time, which is built on .NET 2.0 - it&amp;#39;s not surprising that so much of my benchmark&amp;#39;s time was spent constructing classes, given results like this.&lt;/p&gt;  &lt;p&gt;Of course you can &lt;a href="http://pobox.com/~skeet/csharp/blogfiles/NewConstraint.cs"&gt;download the benchmark program&lt;/a&gt; for yourself and see how it performs on your machine. It&amp;#39;s a pretty cheap-and-cheerful benchmark, but when the differences are this big, minor sources of inaccuracy don&amp;#39;t bother me too much. The simplest way to run under CLR v2 is to compile with the .NET 3.5 C# compiler to start with.&lt;/p&gt;  &lt;h3&gt;What&amp;#39;s going on under the hood?&lt;/h3&gt;  &lt;p&gt;As far as I&amp;#39;m aware, there&amp;#39;s no IL to give support for the new() constraint. Instead, the compiler emits a call to &lt;a href="http://msdn.microsoft.com/en-us/library/0hcyx2kd.aspx"&gt;Activator.CreateInstance&amp;lt;T&amp;gt;&lt;/a&gt;. Apparently, that&amp;#39;s slower than calling a delegate - presumably due to trying to find an accessible constructor with reflection, and invoking it. I suspect it could be optimized relatively easily - e.g. by caching the results per type it&amp;#39;s called with, in terms of delegates. I&amp;#39;m slightly surprised this &lt;em&gt;hasn&amp;#39;t&lt;/em&gt; (apparently) been optimized, given how easy it is to cache values by generic type. No doubt there&amp;#39;s a good reason lurking there somewhere, even if it&amp;#39;s only the memory taken up by the cache.&lt;/p&gt;  &lt;p&gt;Either way, it&amp;#39;s easy to work around in general.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;I wouldn&amp;#39;t have found this gotcha if I didn&amp;#39;t have before and after tests (or in this case, side-by-side tests of the old way and the new way of parsing). The real lesson of this post shouldn&amp;#39;t be about the new() constraint - it should be how important it is to test performance (assuming you care), and how easy it is to assume certain operations are cheap.&lt;/p&gt;  &lt;p&gt;Next post: something much weirder.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1798032" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/JonSkeetCodingBlog/~4/9OK-4m3wBiU" height="1" width="1"/&gt;</description><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Benchmarking/default.aspx">Benchmarking</category><category domain="http://msmvps.com/blogs/jon_skeet/archive/tags/Noda+Time/default.aspx">Noda Time</category><feedburner:origLink>http://msmvps.com/blogs/jon_skeet/archive/2011/08/22/optimization-and-generics-part-1-the-new-constraint.aspx</feedburner:origLink></item></channel></rss>

