<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Dan Crevier's Blog</title><link>http://blogs.msdn.com/b/dancre/</link><description>In search of a better name...</description><dc:language>en-US</dc:language><generator>Telligent Community 5.6.583.19849 (Build: 5.6.583.19849)</generator><item><title>Using the yield pattern with HealthVault on Windows Phone 7 (part 2)</title><link>http://blogs.msdn.com/b/dancre/archive/2011/12/29/using-the-yield-pattern-with-healthvault-on-windows-phone-7-part-2.aspx</link><pubDate>Thu, 29 Dec 2011 06:21:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251656</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=10251656</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2011/12/29/using-the-yield-pattern-with-healthvault-on-windows-phone-7-part-2.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://blogs.msdn.com/b/dancre/archive/2011/12/29/using-the-yield-pattern-with-healthvault-on-windows-phone-7-part-1.aspx"&gt;part 1&lt;/a&gt;, I described the overall design of the HealthVaultTask class. Now, I’ll go through the implementation. First, I’ll get some of the helper classes. Out of the way. The first is the exception type for errors from HealthVault that captures the error code and error text. Note: this implementation doesn’t make the exception serializable, but that would be straightforward to do if needed.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HealthVaultException : Exception
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; HealthVaultException(&lt;span class="kwrd"&gt;int&lt;/span&gt; errorCode, &lt;span class="kwrd"&gt;string&lt;/span&gt; errorText)
    : &lt;span class="kwrd"&gt;base&lt;/span&gt;(errorText)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ErrorCode = errorCode;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; ErrorCode { get; set; }
}&lt;/pre&gt;


&lt;p&gt;Next, is the HealthVaultOperation class. The pattern with this class is that DoOperations yields one of these with the information about the HealthVaultRequest, and when control returns after the yield, the response data will be filled out. It also has a helper function to throw a HealthVaultException in the case of an error. But, it’s up to the DoOperations implementation to call ThrowOnError.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HealthVaultOperation
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; HealthVaultOperation(&lt;span class="kwrd"&gt;string&lt;/span&gt; methodName, &lt;span class="kwrd"&gt;string&lt;/span&gt; methodVersion, XElement info)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.MethodName = methodName;
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.MethodVersion = methodVersion;
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Info = info;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; MethodName { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; MethodVersion { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
    &lt;span class="kwrd"&gt;public&lt;/span&gt; XElement Info { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; HealthVaultResponseEventArgs Response { get; set; }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThrowOnError()
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.HasError)
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; HealthVaultException(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.ErrorCode, &lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.ErrorText);
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Finally, here is the HealthVaultTask class. The only really interesting code is in RunEnumerator, which enumerates through the HealthVaultOperations returned by DoOperation, creating a HealthVaultRequest for it and executing it. At first glance, this function may look recursive, but the other RunEnumerator call is actually in a lamda function that will be called from the request callback. It also has the code to marshal the result (in case of success or failure) to the right callback function on the UI thread.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; HealthVaultTask
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; HealthVaultTask(HealthVaultService service)
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Service = service;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Run(Dispatcher dispatcher, Action successCallback, Action&amp;lt;Exception&amp;gt; errorCallback)
    {
        RunEnumerator(dispatcher, successCallback, errorCallback, DoOperations().GetEnumerator());
    }

    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; RunEnumerator(Dispatcher dispatcher, Action successCallback, Action&amp;lt;Exception&amp;gt; errorCallback,&lt;br /&gt;                               IEnumerator&amp;lt;HealthVaultOperation&amp;gt; operations)
    {
        &lt;span class="kwrd"&gt;try&lt;/span&gt;
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (operations.MoveNext())
            {
                HealthVaultOperation operation = operations.Current;
                HealthVaultRequest request = &lt;span class="kwrd"&gt;new&lt;/span&gt; HealthVaultRequest(operation.MethodName, operation.MethodVersion,&lt;br /&gt;                                                     operation.Info, (o, e) =&amp;gt;
                    {
                        operation.Response = e;
                        RunEnumerator(dispatcher, successCallback, errorCallback, operations);
                    });
                &lt;span class="kwrd"&gt;this&lt;/span&gt;.Service.BeginSendRequest(request);
            }
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                dispatcher.BeginInvoke(() =&amp;gt; successCallback());
            }
        }
        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception e)
        {
            dispatcher.BeginInvoke(() =&amp;gt; errorCallback(e));
        }
    }

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;abstract&lt;/span&gt; IEnumerable&amp;lt;HealthVaultOperation&amp;gt; DoOperations();

    &lt;span class="kwrd"&gt;protected&lt;/span&gt; HealthVaultService Service { get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set; }
}&lt;/pre&gt;

&lt;p&gt;If this doesn’t make sense, please let me know and I’ll explain further.&lt;/p&gt;

&lt;p&gt;There’s one design consideration I didn’t think about until after I’d implemented it. One problem with this implementation is that you can’t compose HealthVaultTasks with other HealthVaultTasks. It would be nice if you could build up layers of reusable service code. This could be accomplished by having a common base class between HealthVaultTask and HealthVaultOperation where HealthVaultTask.DoOperation would be an IEnumerable of the base class. That would let you yield either operations or tasks. This addition is left as an exercise to the reader &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-34-01-metablogapi/7103.wlEmoticon_2D00_smile_5F00_6E04E05E.png" /&gt;&lt;/p&gt;

&lt;p&gt;Finally, a note on unit testing. This framework actually makes the HealthVaultTasks you write very easily unit tested. All you have to do is call GetEnumerator on your task, then call MoveNext/Current to simulate running the task. After you call MoveNext, you can make sure you get the expected operation in Current and you can push whatever results you want into the HealthVaultOperation. What’s great is that the HealthVaultService is completely out of the picture.&lt;/p&gt;

&lt;p&gt;I hope this is useful!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251656" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/WP7/">WP7</category><category domain="http://blogs.msdn.com/b/dancre/archive/tags/HealthVault/">HealthVault</category></item><item><title>Using the yield pattern with HealthVault on Windows Phone 7 (part 1)</title><link>http://blogs.msdn.com/b/dancre/archive/2011/12/29/using-the-yield-pattern-with-healthvault-on-windows-phone-7-part-1.aspx</link><pubDate>Thu, 29 Dec 2011 06:00:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10251651</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=10251651</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2011/12/29/using-the-yield-pattern-with-healthvault-on-windows-phone-7-part-1.aspx#comments</comments><description>  &lt;p&gt;I’ve written a Windows Phone 7 application called &lt;a href="http://weight4.me"&gt;Weight4Me&lt;/a&gt; that lets you track your weight, syncing the data to HealthVault. The first version just fetched all of the weight data from HealthVault on each launch. I’m one of the developers Eric Gunnerson is referring to in &lt;a href="http://blogs.msdn.com/b/ericgu/archive/2011/10/14/mobile-healthvault-apps-and-sync.aspx"&gt;this post&lt;/a&gt;. I’ve just posted an updated release that does a sync with HealthVault (not following exactly what Eric suggests, maybe I’ll post more details about that next). Doing sync, required doing more complex series of operations with HealthVault.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://healthvaultwp7.codeplex.com/"&gt;HealthVault SDK for Windows Phone 7&lt;/a&gt; provides a HealthVaultRequest class for making calls to HealthVault, calling into a callback when done. Using lambda expressions, you can make fairly readable code for simple calls as follows:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;service.BeginSendRequest(new HealthVaultRequest(methodName, methodVersion, xml,&lt;br /&gt;                         (&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, HealthVaultResponseEventArgs e) =&amp;gt;
{
    dispatcher.BeginInvoke(() =&amp;gt;
    {
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (e.HasError)
        {
            &lt;span class="rem"&gt;// Handle error.&lt;/span&gt;
        }

        &lt;span class="rem"&gt;// Parse results.&lt;/span&gt;
    });
}));&lt;/pre&gt;

&lt;p&gt;But, I needed to do some more complex things like do multiple requests in a loop, have branching based on sync state, and so on. This turns into incredibly messy and hard to follow code with callback functions and/or lambdas. A common trick for making asynchronous code read more like synchronous code is to use the yield keyword in C# so that the compiler will build the state machine for you. Jeffrey Richter has a series of articles about using it with the standard async pattern which you can read &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc163323.aspx"&gt;here&lt;/a&gt;. I decided to apply this technique to the HealthVaultService and HealthVaultRequests, which I present here. I hope people will find it useful with HealthVault on Windows Phone 7, or will see how to apply it to similar problems.&lt;/p&gt;

&lt;p&gt;My basic approach is to create a HealthVaultTask class, which runs a series of HealthVaultRequests. This is done by implementing an IEnumerable function that returns a series of HealthVaultOperations. HealthVaultOperation is a new class I am using to encapsulate a HealthVaultRequest and response. So, the way you implement a task looks something like:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; IEnumerable&amp;lt;HealthVaultOperation&amp;gt; DoOperations()
{
    HealthVaultOperation myOperation = &lt;span class="kwrd"&gt;new&lt;/span&gt; HealthVaultOperation(methodName, methodVersion, xml);
    &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; myOperation;&lt;br /&gt;    myOperation.ThrowOnError(); &lt;span class="rem"&gt;// See discussion below.&lt;/span&gt;
    &lt;span class="rem"&gt;// Parse response from myOperation.Response&lt;/span&gt;
}&lt;/pre&gt;

&lt;p&gt;The magic of this pattern is that you can have loops, if branches, etc in DoOperations so that the code in DoOperations looks like serial code. But, under the covers it will all be asynchronous.&lt;/p&gt;

&lt;p&gt;There are a couple of design decisions I had to make up front. The first was about how to handle errors. There can be errors returned from the operations, and exceptions could be thrown from DoOperations itself. One approach would be to put an error code in HealthVaultOperationTask and have the caller check for the error. However, I prefer having all errors just be thrown from DoOperations method and wrapped up by the code that runs the task. To make it simple, HealthVaultOperation has a helper function called ThrowOnError() that throws an exception if there is an error returned from the HealthVault service (wrapped in a new HealthVaultException class).&lt;/p&gt;

&lt;p&gt;The other design decision was around the threading model and how the results are communicated to the caller. I considered two basic approaches:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;DoOperations is always called on the UI thread and can update models/UI as necessary. &lt;/li&gt;

  &lt;li&gt;DoOperations is not called on the UI thread, bundles up its results into properties on the task class, and is marshaled to the UI thread when complete. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I opted for #2. It eliminates potentially unnecessary thread context switching and keeps the code that does the network operation separated from any model/UI code. As a result, the signature of the method to run the task is as follows:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Run(Dispatcher dispatcher, Action successCallback, Action&amp;lt;Exception&amp;gt; errorCallback)&lt;/pre&gt;

&lt;p&gt;When the task is run, either the successCallback will be called or the errorCallback will be called. The call will be dispatched to the UI thread. Here’s an example:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;MyHealthVaultTaskTask task = &lt;span class="kwrd"&gt;new&lt;/span&gt; MyHealthVaultTaskTask (service, ...);
task(dispatcher,
() =&amp;gt; {
    &lt;span class="rem"&gt;// pull results off task and update model/UI.&lt;/span&gt;
},
(e) =&amp;gt; {
    &lt;span class="rem"&gt;// Handle updating model/UI with exception e.&lt;/span&gt;
});&lt;/pre&gt;

&lt;p&gt;In part 2, I’ll share the code that implements HealthVaultTask.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10251651" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/WP7/">WP7</category><category domain="http://blogs.msdn.com/b/dancre/archive/tags/HealthVault/">HealthVault</category></item><item><title>Resetting the Live Tile in Windows Phone 7</title><link>http://blogs.msdn.com/b/dancre/archive/2011/10/19/resetting-the-live-tile-in-windows-phone-7.aspx</link><pubDate>Wed, 19 Oct 2011 16:15:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10227628</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=10227628</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2011/10/19/resetting-the-live-tile-in-windows-phone-7.aspx#comments</comments><description>&lt;p&gt;The ability to update the Live Tile in Mango is a really great feature. I have an application where I’m generating dynamic images and setting the live tile to an isostore:/Shared/ShellContent url. But, I have a setting that the user can use to turn on/off live tile updates. When turning it off, I initially couldn’t figure out how to reset the tile.&lt;/p&gt;  &lt;p&gt;The trick is to use an appdata: url to refer to your original image. For example, if your standard tile image is called “background.png”, then you can use the following to reset it:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ResetTile()
        {
            StandardTileData newTileData = &lt;span class="kwrd"&gt;new&lt;/span&gt; StandardTileData();
            newTileData.BackgroundImage = &lt;span class="kwrd"&gt;new&lt;/span&gt; Uri(&lt;span class="str"&gt;&amp;quot;appdata:background.png&amp;quot;&lt;/span&gt;);

            ShellTile appTile = ShellTile.ActiveTiles.First();
            appTile.Update(newTileData);

        }&lt;/pre&gt;

&lt;p&gt;Note: If you have changed any other properties like the BackContent, you will want to reset them by setting them to “”. Passing in null will leave the values unchanged.&lt;/p&gt;


&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10227628" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>Windows Phone 7 WebBrowser control and target=”_blank”</title><link>http://blogs.msdn.com/b/dancre/archive/2011/09/13/windows-phone-7-webbrowser-control-and-target-blank.aspx</link><pubDate>Tue, 13 Sep 2011 01:54:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10209687</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=10209687</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2011/09/13/windows-phone-7-webbrowser-control-and-target-blank.aspx#comments</comments><description>&lt;p&gt;I recently ran into a problem where I was hosting some content in a WebBrowser in a Windows Phone 7 app and found that some of the links on the page didn’t work. After a bit of debugging and binging, I found that it was because the links had target=”_blank”. In a regular web browser, this opens up the page in a new tab/window. In the WebBrowser control, it silently does nothing – there are no events you can hook into or anything.&lt;/p&gt;  &lt;p&gt;I wanted to share the workaround I used. It’s pretty ugly, but the basic idea is that after the page loads, it injects some JavaScript to go remove the target on any links with target=”_blank”. For this to work, you need to have IsScriptEnabled=true on the control. And, it’s possible that some pages might block eval or otherwise block this from working. But, it worked in my case.&lt;/p&gt;  &lt;p&gt;First, you need to hook up the LoadCompleted event on the web browser control. This fires after a page loads:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; MyPagel()
        {
            InitializeComponent();

            _webBrowser.LoadCompleted += OnWebBrowserLoadCompleted;
        }&lt;/pre&gt;

&lt;p&gt;Then, OnWebBrowserLoadCompleted injects JavaScript to fix up the links:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnWebBrowserLoadCompleted(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, NavigationEventArgs e)
        {
            &lt;span class="kwrd"&gt;try&lt;/span&gt;
            {
                _webBrowser.InvokeScript(&lt;span class="str"&gt;&amp;quot;eval&amp;quot;&lt;/span&gt;,
&lt;span class="str"&gt;@&amp;quot;
window.FixupAnchors=function()
{
    var elems=document.getElementsByTagName('a');
    for (var i=0;i&amp;lt;elems.length;i++)
    {
        if (elems[i].getAttribute('target')!=null &amp;amp;&amp;amp; elems[i].getAttribute('target').indexOf('_blank')==0)
        {
            elems[i].removeAttribute('target');
        }
    }
}&amp;quot;&lt;/span&gt;);
                _webBrowser.InvokeScript(&lt;span class="str"&gt;&amp;quot;FixupAnchors&amp;quot;&lt;/span&gt;);
            }
            &lt;span class="kwrd"&gt;catch&lt;/span&gt;
            {
                &lt;span class="rem"&gt;// ignore exceptions.&lt;/span&gt;
            }
        }&lt;/pre&gt;

&lt;p&gt;It’s a bit ugly, and some of my coworkers will give me a hard time for swallowing all exceptions here. But, it is working for me and hopefully someone will find it useful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10209687" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/Windows+Phone/">Windows Phone</category></item><item><title>Hello World</title><link>http://blogs.msdn.com/b/dancre/archive/2011/09/13/hello-world.aspx</link><pubDate>Tue, 13 Sep 2011 01:35:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10209684</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=10209684</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2011/09/13/hello-world.aspx#comments</comments><description>&lt;p&gt;Is this thing on? &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-34-01-metablogapi/8030.wlEmoticon_2D00_smile_5F00_6EFF2BC8.png" /&gt;&lt;/p&gt;  &lt;p&gt;I am going to pick up blogging again. It’s been a while! First off, I want to give an update on what I’ve been up to for the last few years since my last post. I was the development lead on SkyDrive from its initial release up through our Wave 4 release about 4 years ago. It was a lot of fun helping SkyDrive grow from a small beta (Windows Live Folders) up to a major service that tightly integrates with several other properties in Microsoft including Office and Windows Phone 7.&lt;/p&gt;  &lt;p&gt;As of a year ago, I’ve moved over to be the development manager in the Engineering Platform team in Windows Live. My team is in charge of the infrastructure that runs Windows Live. This includes:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Our build system including our automated test and builds to keep the team running efficiently.&lt;/li&gt;    &lt;li&gt;Our system for packaging and deploying client builds, including Windows Live Essentials and the new Windows 8 applications.&lt;/li&gt;    &lt;li&gt;The system we use to manage our services (Hotmail, Messenger, SkyDrive, etc) including deployment, monitoring and repair.&lt;/li&gt;    &lt;li&gt;Our analytics system that is used to monitor service health and understand how users are using our clients and services.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are lots of hard problems in these areas and I’ve been learning a lot over the last year.&lt;/p&gt;  &lt;p&gt;I’ve also been doing some Windows Phone development in my free time and recently published my first application (&lt;a href="http://bit.ly/wifiscaletracker"&gt;WiFi Scale Tracker&lt;/a&gt;). I’m planning to do some blog posts both about Windows Phone development and what we are doing in Windows Live.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10209684" width="1" height="1"&gt;</description></item><item><title>News on the upcoming SkyDrive release</title><link>http://blogs.msdn.com/b/dancre/archive/2008/11/12/news-on-the-upcoming-skydrive-release.aspx</link><pubDate>Thu, 13 Nov 2008 08:12:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9065420</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=9065420</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/11/12/news-on-the-upcoming-skydrive-release.aspx#comments</comments><description>&lt;p&gt;We’ve posted some details of our upcoming SkyDrive release &lt;a href="http://skydriveteam.spaces.live.com/blog/cns!977F793E846B3C96!11672.entry"&gt;here&lt;/a&gt;. I’m really excited about what’s coming all across Windows Live with our wave 3 release and how well everything works together.&lt;/p&gt; &lt;p&gt;I’m sorry I haven’t been posting much lately There are a bunch of topics I want to write about, like ASP.NET MVC, PowerShell and Silverlight!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9065420" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/SkyDrive/">SkyDrive</category></item><item><title>Font Smoothing with Remote Desktop and Windows Server 2003</title><link>http://blogs.msdn.com/b/dancre/archive/2008/07/11/font-smoothing-with-remote-desktop-and-windows-server-2003.aspx</link><pubDate>Sat, 12 Jul 2008 06:42:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8722448</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8722448</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/07/11/font-smoothing-with-remote-desktop-and-windows-server-2003.aspx#comments</comments><description>&lt;p&gt;I spend a lot of time time connected to Windows 2003 Server. I was really happy to come across this post which describes a KB article to turn on font smoothing to Windows 2003 Server. This makes a huge difference with Consolas&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.sepago.de/helge/2008/07/08/finally-font-smoothing-over-rdpica-on-server-2003/"&gt;Helge Klein » Blog Archive » Finally! Font Smoothing Over RDP/ICA on Server 2003&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8722448" width="1" height="1"&gt;</description></item><item><title>Disappearing disk space on Vista</title><link>http://blogs.msdn.com/b/dancre/archive/2008/06/08/disappearing-disk-space-on-vista.aspx</link><pubDate>Mon, 09 Jun 2008 07:01:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8583260</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8583260</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/06/08/disappearing-disk-space-on-vista.aspx#comments</comments><description>&lt;p&gt;The hard drive space on my Vista machine recently dropped to almost nothing, and I was really confused what was going on. I used my favorite disk space visualizer (&lt;a href="http://windirstat.info/"&gt;WinDirStat&lt;/a&gt;). However, I couldn’t figure it out. Finally, I found that the following steps cleared it up:&lt;/p&gt; &lt;p&gt;1. Run Disk Cleanup (search from Start menu) &lt;p&gt;2. Choose “Files from all users on this computer” &lt;p&gt;3. When it’s done scanning (which can take forever), select the More Options tab &lt;p&gt;4. Select Cleanup under System Restore and Shadow Copies &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;This freed over 40 GB for me! I think that what happened is that the Zune software touched all of my media, which created shadow copies of each file, using a bunch of space. Shadow copy space must not show up for utilities like WinDirStat.&lt;/p&gt; &lt;p&gt;There’s a useful article on &lt;a href="http://www.mydigitallife.info/2007/06/26/how-to-change-and-limit-system-restore-storage-space-usage-size-in-vista-with-vssadmin/"&gt;My Digital Life&lt;/a&gt; on how to limit how much space will be used. My was set to unbounded space.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8583260" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/Vista/">Vista</category></item><item><title>New updates to SkyDrive!</title><link>http://blogs.msdn.com/b/dancre/archive/2008/05/22/new-updates-to-skydrive.aspx</link><pubDate>Thu, 22 May 2008 20:19:12 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8532586</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8532586</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/05/22/new-updates-to-skydrive.aspx#comments</comments><description>&lt;p&gt;We’ve made some more updates to SkyDrive including some features like comments, captions and better iteration through items in a folder. For details, check out our team blog post: &lt;/p&gt; &lt;p&gt;&lt;a href="http://skydriveteam.spaces.live.com/blog/cns!977F793E846B3C96!3837.entry"&gt;Windows Live SkyDrive Team Blog: Hot new updates to SkyDrive!&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8532586" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/SkyDrive/">SkyDrive</category></item><item><title>Bootcamp 2.1 update available</title><link>http://blogs.msdn.com/b/dancre/archive/2008/05/16/bootcamp-2-1-update-available.aspx</link><pubDate>Sat, 17 May 2008 04:51:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8516178</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8516178</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/05/16/bootcamp-2-1-update-available.aspx#comments</comments><description>&lt;p&gt;Apple has an update of Bootcamp available, fixing some stability issues. I’ve had more than my fair share of crashes on my MacBook Pro, so I’m hoping it will help out. It was offered to me via Apple Software Update, but you can also grab it here: &lt;/p&gt; &lt;p&gt;&lt;a href="http://www.apple.com/support/bootcamp/"&gt;Apple - Support - Bootcamp&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8516178" width="1" height="1"&gt;</description></item><item><title>Implications of the just in time nature of LINQ</title><link>http://blogs.msdn.com/b/dancre/archive/2008/03/25/implications-of-the-just-in-time-nature-of-linq.aspx</link><pubDate>Wed, 26 Mar 2008 05:30:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8337025</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8337025</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/03/25/implications-of-the-just-in-time-nature-of-linq.aspx#comments</comments><description>&lt;p&gt;I love LINQ! I’ve found that much of the code I write involves manipulating collections in ways that can be very naturally expressed in LINQ. One interesting aspect of LINQ is that things are evaluated just in time as you enumerate over them. This can have a few unexpected consequences. Here are a couple of examples. Take the following test class:&lt;/p&gt;&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Test
        {
            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Value { get; set; }
        }
&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Now, think about the following code:&lt;/p&gt;&lt;pre class="csharpcode"&gt;            IEnumerable&amp;lt;Test&amp;gt; tests = Enumerable.Range(1, 3).Select(i =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Value = i });

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Test test &lt;span class="kwrd"&gt;in&lt;/span&gt; tests)
            {
                test.Value += 100;
            }

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Test test &lt;span class="kwrd"&gt;in&lt;/span&gt; tests)
            {
                Console.WriteLine(test.Value);
            }
&lt;/pre&gt;
&lt;p&gt;For those not familiar with LINQ, the Enumerable.Range(1, 3) creates an IEumerable that ranges from 1 to 3, and then the Select creates new Test objects with a Value equal to the current value, meaning the overall expression creates Tests with values that range from 1 to 3. So, what does this output? You might expect 101, 102, and 103 because the first foreach increments the values. However, it prints 1, 2, 3. The reason is that foreach calls tests.GetEnumerator which runs through the process of creating Test objects as MoveNext/Current is called through the foreach loop. So, the first time we go though the loop it creates 3 Test objects and we increment the value. However, those Test objects are just returned by the enumerator and don’t get stored anywhere. The second time we go through the loop we create 3 new Test objects with values 1-3. One way to get the expected behavior would be to replace the first line with:&lt;/p&gt;&lt;pre class="csharpcode"&gt;            List&amp;lt;Test&amp;gt; tests = Enumerable.Range(1, 3).Select(i =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Value = i }).ToList();&lt;/pre&gt;
&lt;p&gt;This creates a list with the Test values once, and then the foreach statements will enumerate the same set of Test values in that list.&lt;/p&gt;
&lt;p&gt;Another gotcha of the just in time evaluation is that values in the lambda functions are evaluated at the time of enumeration. So, in the following example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;            &lt;span class="kwrd"&gt;int&lt;/span&gt; x = 0;

            tests = Enumerable.Range(1, 3).Select(i =&amp;gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Test() { Value = x + i });

            x = 100;

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (Test test &lt;span class="kwrd"&gt;in&lt;/span&gt; tests)
            {
                Console.WriteLine(test.Value);
            }&lt;/pre&gt;
&lt;p&gt;You get 101, 102, and 103 output. That’s because the “x + i” expression is evaluated after x is set to 100. This sort of issue is more subtle when you return a LINQ expression from a function. Who knows when that will be evaluated and what will change by then. Using ToList() is a reasonable way to force the evaluation time.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8337025" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/-Net+development/">.Net development</category></item><item><title>Why does my computer need to tell me when I plug into the headphone jack?</title><link>http://blogs.msdn.com/b/dancre/archive/2008/03/20/why-does-my-computer-need-to-tell-me-when-i-plug-into-the-headphone-jack.aspx</link><pubDate>Thu, 20 Mar 2008 23:16:25 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8327852</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8327852</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/03/20/why-does-my-computer-need-to-tell-me-when-i-plug-into-the-headphone-jack.aspx#comments</comments><description>&lt;p&gt;And, why is the icon so ugly?&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/dancre/WindowsLiveWriter/WhydoesmycomputerneedtotellmewhenIplugin_BAA7/image_4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="66" alt="image" src="http://blogs.msdn.com/blogfiles/dancre/WindowsLiveWriter/WhydoesmycomputerneedtotellmewhenIplugin_BAA7/image_thumb_1.png" width="244" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8327852" width="1" height="1"&gt;</description></item><item><title>mstsc /console is now /admin in Vista SP1</title><link>http://blogs.msdn.com/b/dancre/archive/2008/03/19/mstsc-console-is-now-admin-in-vista-sp1.aspx</link><pubDate>Thu, 20 Mar 2008 05:37:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8326808</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8326808</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/03/19/mstsc-console-is-now-admin-in-vista-sp1.aspx#comments</comments><description>&lt;p&gt;I find it kind of annoying that Vista SP1 switches the /console switch to /admin. I don't understand why they had to break this and couldn't keep the old switch working. There's a bit more info at:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/nickmac/archive/2007/11/28/mstsc-console-switch-in-windows-server-2008-and-windows-vista-sp1.aspx"&gt;Nick MacKechnie : MSTSC /console switch in Windows Server 2008 and Windows Vista SP1&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8326808" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/Vista/">Vista</category></item><item><title>Yield and usings - your Dispose may not be called!</title><link>http://blogs.msdn.com/b/dancre/archive/2008/03/14/yield-and-usings-your-dispose-may-not-be-called.aspx</link><pubDate>Sat, 15 Mar 2008 07:08:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8218319</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8218319</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/03/14/yield-and-usings-your-dispose-may-not-be-called.aspx#comments</comments><description>&lt;p&gt;We ran into an interesting bug recently where a resource was being leaked because we weren't disposing of an IDisposable in some cases. Before I go any further I should state that the root bug is that the IDisposable hanging onto the resource should have implemented a finalizer, or even better, used &lt;a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx"&gt;SafeHandle&lt;/a&gt;. However it wasn't our code.&lt;/p&gt; &lt;p&gt;We tracked down the bug to some code that looked like:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;Foo&amp;gt; MyEnumerable()
    {
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (&lt;span class="kwrd"&gt;new&lt;/span&gt; MyDisposable())
        {
            &lt;span class="rem"&gt;// code that calls yield&lt;/span&gt;
        }
    }&lt;/pre&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Then, someone called MyEnumerable().GetEnumerator().MoveNext() without disposing it or wrapping it in a foreach. The result was that Dispose was never called on the disposable. I usually think of using guaranteeing that Dispose() gets called, except in extreme cases like thread abort exceptions. It sparked my curiosity to dig and figure out how this all works.&lt;/p&gt;
&lt;p&gt;First, a couple of words about Enumerables, Enumerators and yield. An IEnumerator provides a simple way to iterate through a collection, using MoveNext() to advance to the next element, and a property Current to get the value at the current position. MoveNext() returns false at the end of the collection. An IEnumerable is simply an object you can call GetEnumerator() on to get an IEnumerator you can use to enumerate it (for example, collections are IEnumerables).&lt;/p&gt;
&lt;p&gt;The yield keyword is a handy way to implement an IEnumerable that exposes the result of a series of calculations or operations in such a way that you can write serial code. I could spend a whole post on how cool yield is, but you can find that elsewhere. For a cool example, you can see the &lt;a href="http://www.differentpla.net/content/2007/06/generating-the-fibonacci-sequence-by-using-the-yield-keyword-non-recursively"&gt;Fibonacci series implemented using yield&lt;/a&gt;. Note: yield is not a feature of the CLR, it's magical syntactic sugar provided by C# 2.0.&lt;/p&gt;
&lt;p&gt;Let's take a simple example:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; MyDisposable : IDisposable
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose()
        {
            Console.WriteLine(&lt;span class="str"&gt;"Disposed"&lt;/span&gt;);
        }
    }&lt;/pre&gt;
&lt;p&gt;and the function:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; MyEnumerable()
    {
        &lt;span class="kwrd"&gt;using&lt;/span&gt; (&lt;span class="kwrd"&gt;new&lt;/span&gt; MyDisposable())
        {
            &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; 1;
            &lt;span class="kwrd"&gt;yield&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; 2;
        }
        Console.WriteLine(&lt;span class="str"&gt;"complete"&lt;/span&gt;);
    }&lt;/pre&gt;
&lt;p&gt;If you walk the collection with the following code:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    IEnumerator&amp;lt;&lt;span class="kwrd"&gt;int&lt;/span&gt;&amp;gt; enumerator = MyEnumerable().GetEnumerator();
    &lt;span class="kwrd"&gt;while&lt;/span&gt; (enumerator.MoveNext())
    {
        Console.WriteLine(enumerator.Current);
    }
&lt;/pre&gt;
&lt;p&gt;It will print "1", "2", "Disposed", "complete". But, how does it work? If you were to implement this without yield, you'd probably have to create a gnarly state machine, with some special cases for cleanup. Well, that's exactly what the C# compiler does for you!&lt;/p&gt;
&lt;p&gt;Using &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;.NET Reflector&lt;/a&gt;, we can see what code is generated. The MyEnumerable() function returns a new instance of a compiler generated class. Leaving out some of the details, the core of MoveNext() looks like:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;switch&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state)
    {
        &lt;span class="kwrd"&gt;case&lt;/span&gt; 0:
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = -1;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;7__wrap1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; MyDisposable();
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 1;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;2__current = 1;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 2;
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;

        &lt;span class="kwrd"&gt;case&lt;/span&gt; 2:
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 1;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;2__current = 2;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 3;
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;

        &lt;span class="kwrd"&gt;case&lt;/span&gt; 3:
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = 1;
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;m__Finally2();
            Console.WriteLine(&lt;span class="str"&gt;"complete"&lt;/span&gt;);
            &lt;span class="kwrd"&gt;break&lt;/span&gt;;
    }
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;With:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; &amp;lt;&amp;gt;m__Finally2()
    {
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;1__state = -1;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;7__wrap1 != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
        {
            &lt;span class="kwrd"&gt;this&lt;/span&gt;.&amp;lt;&amp;gt;7__wrap1.Dispose();
        }
    }&lt;/pre&gt;
&lt;p&gt;So, if you walk through the states, you can see in case 0, it creates the MyDisposable, sets current to 1 and returns true. When it's called again in state 2, it sets current to 2 and returns true. When it's called a third time, it calls the finally function that disposes of the MyDisposable and then writes out "complete".&lt;/p&gt;
&lt;p&gt;But, what happens in a partial enumeration? If you use foreach, like:&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i &lt;span class="kwrd"&gt;in&lt;/span&gt; MyEnumerable())
    {
        Console.WriteLine(i);
        &lt;span class="kwrd"&gt;break&lt;/span&gt;;
    }&lt;/pre&gt;
&lt;p&gt;You might not expect it to call dispose. But, what it outputs is "1", "Disposed". The reason that this works is that the generated IEnumerator class also implements IDisposable where Dispose() calls &amp;lt;&amp;gt;m__Finally2(). And, foreach calls Dispose on its enumerator if it is an IDisposable.&lt;/p&gt;
&lt;p&gt;However, in the case of our bug, we weren't using a foreach, we were just using MoveNext/Current directly without enumerating through the entire list. In this case, the MyDisposable is never disposed, even when GC takes place. Is this a bug? I've gone back in forth in my mind. On the one hand, the Enumerable code has a using, and that's supposed to clean things up! The compiler could have implemented a finalizer for the temporary class to clean up. On the other hand, the IEnumerator it generated was an IDisposable, which we failed to dispose. I tend to land on the side that this isn't a bug (and I bet the C# team agrees). If you have something that's holding onto a critical resource, you should implement a finalizer or use a SafeHandle and not rely on Dispose being called. However, I did find it a bit surprising. Now I know!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8218319" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/-Net+development/">.Net development</category></item><item><title>Josh Zana's perf blog</title><link>http://blogs.msdn.com/b/dancre/archive/2008/03/11/josh-zana-s-perf-blog.aspx</link><pubDate>Wed, 12 Mar 2008 07:34:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8165741</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8165741</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/03/11/josh-zana-s-perf-blog.aspx#comments</comments><description>&lt;p&gt;One of my coworkers, Josh Zana, has started a &lt;a href="http://blogs.msdn.com/joshzana"&gt;perf blog&lt;/a&gt;. Josh has been the perf champion for the &lt;a href="http://skydrive.live.com/"&gt;SkyDrive&lt;/a&gt; and &lt;a href="http://foldershare.com"&gt;FolderShare&lt;/a&gt; websites, and I've been really impressed by his passion about perf and the results. I hope to see lots of good posts coming up.&lt;/p&gt; &lt;p&gt;Speaking of which, I realized I haven't had any technical posts for far too long. I need to get back to it!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8165741" width="1" height="1"&gt;</description></item><item><title>FolderShare updates</title><link>http://blogs.msdn.com/b/dancre/archive/2008/03/11/foldershare-updates.aspx</link><pubDate>Wed, 12 Mar 2008 07:31:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8165730</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=8165730</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/03/11/foldershare-updates.aspx#comments</comments><description>&lt;p&gt;Yesterday, we released a new version of the &lt;a href="http://www.foldershare.com"&gt;FolderShare&lt;/a&gt; web site and client. My team worked on the web site, which you might guess from the similarity to SkyDrive. In case you aren't familiar with FolderShare, it's an application that lets you sync files from multiple machines, peer-to-peer. I've been a happy FolderShare user for many years (since before Microsoft acquired it), and am glad to be a part of making it better. We did extensive usability testing on the core FolderShare scenarios and are really happy with the improvements we've seen with the new site.&lt;/p&gt; &lt;p&gt;Before you ask, I can't comment on FolderShare future plans, but rest assured, it's not dead!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8165730" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/FolderShare/">FolderShare</category></item><item><title>SkyDrive is out of beta</title><link>http://blogs.msdn.com/b/dancre/archive/2008/02/21/skydrive-is-out-of-beta.aspx</link><pubDate>Thu, 21 Feb 2008 21:13:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7840536</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=7840536</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/02/21/skydrive-is-out-of-beta.aspx#comments</comments><description>&lt;p&gt;We released SkyDrive to 38 more regions, we're out of beta, and we now give everyone 5 GB of free storage. See the team &lt;a href="http://skydriveteam.spaces.live.com/blog/"&gt;post&lt;/a&gt; for details.&amp;nbsp; We also made some significant performance enhancements that hopefully everyone should notice.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7840536" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/SkyDrive/">SkyDrive</category></item><item><title>Why do iTunes updates keep making me reboot?</title><link>http://blogs.msdn.com/b/dancre/archive/2008/01/15/why-do-itunes-updates-keep-making-me-reboot.aspx</link><pubDate>Tue, 15 Jan 2008 23:44:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7120430</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=7120430</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/01/15/why-do-itunes-updates-keep-making-me-reboot.aspx#comments</comments><description>&lt;p&gt;Very annoying...&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7120430" width="1" height="1"&gt;</description></item><item><title>A WPF Framework</title><link>http://blogs.msdn.com/b/dancre/archive/2008/01/07/a-wpf-framework.aspx</link><pubDate>Tue, 08 Jan 2008 07:31:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7023753</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=7023753</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2008/01/07/a-wpf-framework.aspx#comments</comments><description>&lt;p&gt;Rob Eisenberg posted a new WPF Framework &lt;a href="http://devlicio.us/blogs/rob_eisenberg/archive/2008/01/07/introducing-caliburn-an-mvc-mvp-wpf-framework.aspx"&gt;here&lt;/a&gt;. I haven't looked at it in detail, but it looks pretty interesting!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7023753" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/WPF/">WPF</category></item><item><title>More SkyDrive goodness</title><link>http://blogs.msdn.com/b/dancre/archive/2007/10/11/more-skydrive-goodness.aspx</link><pubDate>Fri, 12 Oct 2007 01:35:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5407530</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=5407530</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2007/10/11/more-skydrive-goodness.aspx#comments</comments><description>&lt;p&gt;We've updated &lt;a href="http://skydrive.live.com/"&gt;SkyDrive&lt;/a&gt; with some nice new features. One of the biggest hassles with SkyDrive before that was that it was hard to invite new people or add new contacts to the list. We now allow you to add new contacts (whether or not they have Live IDs) and people will be sent invites. If they don't have a Live ID, they'll have the opportunity to set one up. This should make sharing much nicer.&lt;/p&gt; &lt;p&gt;Another thing we added is RSS feeds. For example, the feed to my public folder where I put blog related stuff is:&lt;/p&gt; &lt;p&gt;&lt;a title="http://cid-f9dac4c43e9a681d.skydrive.live.com/feed.aspx/Blog" href="http://cid-f9dac4c43e9a681d.skydrive.live.com/feed.aspx/Blog"&gt;http://cid-f9dac4c43e9a681d.skydrive.live.com/feed.aspx/Blog&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For more details on the new features, see the &lt;a href="http://skydriveteam.spaces.live.com"&gt;SkyDrive blog&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5407530" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/SkyDrive/">SkyDrive</category></item><item><title>Frustrating error using Remote Desktop</title><link>http://blogs.msdn.com/b/dancre/archive/2007/08/22/frustrating-error-using-remote-desktop.aspx</link><pubDate>Thu, 23 Aug 2007 07:22:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4519943</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=4519943</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2007/08/22/frustrating-error-using-remote-desktop.aspx#comments</comments><description>&lt;p&gt;Recently I've started hitting the error below when trying to connect to one of my Windows 2003 Server machines with the /console option:&lt;/p&gt; &lt;p&gt;&lt;img height="134" src="http://blogs.msdn.com/blogfiles/dancre/WindowsLiveWriter/FrustratingerrorusingRemoteDesktop_12C7C/clip_image002.jpg" width="525"&gt;&lt;/p&gt; &lt;p&gt;(Error connecting to existing session for dancre (Id 0). The operation completed successfully.)&lt;/p&gt; &lt;p&gt;You've got to love an error explanation of "The operation completed successfully". Restarting the server box fixes it for a while, but then it starts happening again.&lt;/p&gt; &lt;p&gt;Has anyone else seen this? Any idea how to fix it?&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4519943" width="1" height="1"&gt;</description></item><item><title>Tafiti</title><link>http://blogs.msdn.com/b/dancre/archive/2007/08/21/tafiti.aspx</link><pubDate>Wed, 22 Aug 2007 06:58:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4503888</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=4503888</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2007/08/21/tafiti.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.tafiti.com"&gt;Tafiti&lt;/a&gt; is an interesting search experience built on top of Windows Live Search and SilverLight. Be sure to click the tree view. It's pretty cool stuff, &lt;a href="http://www.jacksonfish.com/blog/2007/08/21/a-new-search-experience/"&gt;from some people I used to work with&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4503888" width="1" height="1"&gt;</description></item><item><title>Windows Live SkyDrive/Spaces integration</title><link>http://blogs.msdn.com/b/dancre/archive/2007/08/09/windows-live-skydrive-spaces-integration.aspx</link><pubDate>Fri, 10 Aug 2007 07:05:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4317531</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=4317531</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2007/08/09/windows-live-skydrive-spaces-integration.aspx#comments</comments><description>&lt;p&gt;Another feature that went live today is the ability to add a "Files" module to Spaces that shows the visitors to your Space the folders they have access to. LiveSide blogs about it &lt;a href="http://www.liveside.net/blogs/main/archive/2007/08/09/skydrive-with-spaces-and-writer.aspx"&gt;here&lt;/a&gt;. Scott also has a nice plugin for Windows Live Writer that makes it easy to embed things in Writer. Nice work!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4317531" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/SkyDrive/">SkyDrive</category></item><item><title>Windows Live Folders is now Windows Live SkyDrive!</title><link>http://blogs.msdn.com/b/dancre/archive/2007/08/09/windows-live-folders-is-now-windows-live-skydrive.aspx</link><pubDate>Thu, 09 Aug 2007 20:22:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4312457</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=4312457</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2007/08/09/windows-live-folders-is-now-windows-live-skydrive.aspx#comments</comments><description>&lt;p&gt;We have updated Windows Live Folders and rebranded it as &lt;a href="http://skydrive.live.com"&gt;Windows Live SkyDrive&lt;/a&gt;.&amp;nbsp;There are lots of cool new features. One of my favorites is the rich upload experience that lets you easily upload lots of files at once, including drag and drop. You can also view the home page for other users, see recent folders you been to, and you can embed thing into your blog. For example, here's where I'm putting blog related files:&lt;/p&gt;&lt;iframe style="border-right: #dde5e9 1px solid; padding-right: 0px; border-top: #dde5e9 1px solid; padding-left: 0px; padding-bottom: 0px; margin: 3px; border-left: #dde5e9 1px solid; width: 240px; padding-top: 0px; border-bottom: #dde5e9 1px solid; height: 66px; background-color: #ffffff" marginwidth="0" marginheight="0" src="http://cid-f9dac4c43e9a681d.skydrive.live.com/embedrowdetail.aspx/Blog/" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;p&gt;Try it out!&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4312457" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/SkyDrive/">SkyDrive</category></item><item><title>A pattern for unit testable Asp.net pages: Part 4</title><link>http://blogs.msdn.com/b/dancre/archive/2007/07/31/a-pattern-for-unit-testable-asp-net-pages-part-4.aspx</link><pubDate>Wed, 01 Aug 2007 06:52:19 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4159856</guid><dc:creator>Dan Crevier</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.msdn.com/b/dancre/rsscomments.aspx?WeblogPostID=4159856</wfw:commentRss><comments>http://blogs.msdn.com/b/dancre/archive/2007/07/31/a-pattern-for-unit-testable-asp-net-pages-part-4.aspx#comments</comments><description>&lt;p&gt;Okay, now for unit tests of the code from &lt;a href="http://blogs.msdn.com/dancre/archive/2007/07/25/a-pattern-for-unit-testable-asp-net-pages-part-3.aspx"&gt;part 3&lt;/a&gt;. The goal is to completely cover RenamePageModel. First we need mock implementations of IPageContext and IDataAccess. For IPageContext, we are going to use special exception types for page not found and server errors. And, we'll add an accessor to track redirects. It's all pretty straightforward.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MockPageContext : IPageContext
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsSecureConnection
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _isSecureConnection; }
            set { _isSecureConnection = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IsPost
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _isPost; }
            set { _isPost = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThrowPageNotFound()
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageNotFoundException();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; ThrowServerError()
        {
            &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; MockServerErrorException();
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Redirect(&lt;span class="kwrd"&gt;string&lt;/span&gt; destination)
        {
            _redirectString = destination;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; HasRedirected
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _redirectString != &lt;span class="kwrd"&gt;null&lt;/span&gt;; }
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; RedirectUrl
        {
            get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _redirectString; }
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; _isSecureConnection;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; _isPost;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _redirectString;
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MockPageNotFoundException : Exception
    {
    }

    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MockServerErrorException : Exception
    {
    }
&lt;/pre&gt;
&lt;p&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;/p&gt;
&lt;p&gt;The IDataAccess mock is also pretty straightforward. It's simply got properties that can be used to set the return value for the function, or to throw exceptions if desired.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; MockDataAccess : IDataAccess
    {
        &lt;span class="kwrd"&gt;public&lt;/span&gt; MockDataAccess(&lt;span class="kwrd"&gt;string&lt;/span&gt; getItemNameResult, Exception getItemNameException, &lt;span class="kwrd"&gt;string&lt;/span&gt; setItemNameResult, Exception setItemNameException)
        {
            _getItemNameResult = getItemNameResult;
            _getItemNameException = getItemNameException;
            _setItemNameResult = setItemNameResult;
            _setItemNameException = setItemNameException;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetItemName(&lt;span class="kwrd"&gt;string&lt;/span&gt; path)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_getItemNameException != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; _getItemNameException;
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; _getItemNameResult;
        }

        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; SetItemName(&lt;span class="kwrd"&gt;string&lt;/span&gt; path, &lt;span class="kwrd"&gt;string&lt;/span&gt; newName)
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (_setItemNameException != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
            {
                &lt;span class="kwrd"&gt;throw&lt;/span&gt; _setItemNameException;
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; _setItemNameResult;
        }

        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _getItemNameResult;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; Exception _getItemNameException;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; _setItemNameResult;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; Exception _setItemNameException;
    }
&lt;/pre&gt;
&lt;p&gt;And, now for the actual unit tests. Basically there's a test for each code path on load or post.&lt;/p&gt;&lt;pre class="csharpcode"&gt;    [TestClass]
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; RenamePageModelTests
    {
        [TestMethod]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLoadSuccess()
        {
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext());
            Assert.AreEqual(&lt;span class="str"&gt;"name"&lt;/span&gt;, model.Name, &lt;span class="str"&gt;"Name not set from item name"&lt;/span&gt;);
        }

        [TestMethod]
        [ExpectedException(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MockPageNotFoundException))]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLoadFileNotFoundException()
        {
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; FileNotFoundException(), &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext());
        }

        [TestMethod]
        [ExpectedException(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MockPageNotFoundException))]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLoadUnauthorizedAccessException()
        {
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; UnauthorizedAccessException(), &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext());
        }

        [TestMethod]
        [ExpectedException(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MockServerErrorException))]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestLoadIOException()
        {
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; IOException(), &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(&lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext());
        }

        [TestMethod]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestPostSuccess()
        {
            MockPageContext pageContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext();
            pageContext.IsPost = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="str"&gt;"newpath"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(pageContext);
            Assert.AreEqual(&lt;span class="str"&gt;"rename.aspx?path=newpath"&lt;/span&gt;, pageContext.RedirectUrl, &lt;span class="str"&gt;"Did not redirect to correct url"&lt;/span&gt;);
        }

        [TestMethod]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestPostArgumentException()
        {
            MockPageContext pageContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext();
            pageContext.IsPost = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; ArgumentException());
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Name = &lt;span class="str"&gt;"errorName"&lt;/span&gt;;
            model.Load(pageContext);
            Assert.AreEqual(&lt;span class="str"&gt;"errorName"&lt;/span&gt;, model.Name, &lt;span class="str"&gt;"New name not returned in model.Name"&lt;/span&gt;);
            Assert.IsNotNull(model.ErrorString, &lt;span class="str"&gt;"Error string not set"&lt;/span&gt;);
        }

        [TestMethod]
        [ExpectedException(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MockPageNotFoundException))]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestPostFileNotFoundException()
        {
            MockPageContext pageContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext();
            pageContext.IsPost = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; FileNotFoundException());
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(pageContext);
        }

        [TestMethod]
        [ExpectedException(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MockPageNotFoundException))]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestPostUnauthorizedAccessException()
        {
            MockPageContext pageContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext();
            pageContext.IsPost = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; UnauthorizedAccessException());
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(pageContext);
        }

        [TestMethod]
        [ExpectedException(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(MockServerErrorException))]
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestPostIOException()
        {
            MockPageContext pageContext = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockPageContext();
            pageContext.IsPost = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            MockDataAccess mockDataAccess = &lt;span class="kwrd"&gt;new&lt;/span&gt; MockDataAccess(&lt;span class="str"&gt;"name"&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="kwrd"&gt;new&lt;/span&gt; IOException());
            RenamePageModel model = &lt;span class="kwrd"&gt;new&lt;/span&gt; RenamePageModel(mockDataAccess, &lt;span class="str"&gt;"foo"&lt;/span&gt;);
            model.Load(pageContext);
        }
&lt;/pre&gt;
&lt;p&gt;If you use Visual Studio .Net's handy code coverage coloring, you'll see that we are covering all the code in the model, except for some closing tags in exceptions that are never hit because of the IPageContext functions that throw exceptions.&lt;/p&gt;
&lt;p&gt;Well, that's it! I've put the entire project on&amp;nbsp;Windows Live&amp;nbsp;SkyDrive:&lt;/p&gt;&lt;iframe style="border-right: #dde5e9 1px solid; padding-right: 0px; border-top: #dde5e9 1px solid; padding-left: 0px; padding-bottom: 0px; margin: 3px; border-left: #dde5e9 1px solid; width: 240px; padding-top: 0px; border-bottom: #dde5e9 1px solid; height: 66px; background-color: #ffffff" marginwidth="0" marginheight="0" src="http://cid-f9dac4c43e9a681d.skydrive.live.com/embedrowdetail.aspx/Blog/PageModelPattern.zip" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;
&lt;p&gt;Let me know if you have any questions on it. And, let me know if there are other areas you'd like me to write about, such as using the asynchronous model. I'm interested to hear feedback on how this model can be adapted for other types of web apps.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4159856" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/b/dancre/archive/tags/ASP-NET/">ASP.NET</category><category domain="http://blogs.msdn.com/b/dancre/archive/tags/PageModel/">PageModel</category></item></channel></rss>
