<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss1full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/" xmlns="http://purl.org/rss/1.0/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

<channel rdf:about="http://bradwilson.typepad.com/blog/">
<title>Brad Wilson</title>
<link>http://bradwilson.typepad.com/blog/</link>
<description>Technologist. Agile Evangelist. Poker Player. Amateur Neologist. Metalhead. Fire Child.</description>
<dc:language>en-US</dc:language>
<dc:creator />
<dc:date>2012-04-28T18:18:50-07:00</dc:date>
<admin:generatorAgent rdf:resource="http://www.typepad.com/" />


<items>
<rdf:Seq><rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt4.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt3.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt2.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/04/xunit-moving-to-git.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/03/win8-cp-on-ss7s.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2012/01/xunit19.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2011/12/best-music-of-2011.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2011/11/win8-dp-on-samsung-series-7-slate.html" />
<rdf:li rdf:resource="http://bradwilson.typepad.com/blog/2011/09/making-hyper-v-internal-network-private.html" />
</rdf:Seq>
</items>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rdf+xml" href="http://feeds.feedburner.com/BradWilson" /><feedburner:info uri="bradwilson" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>47.677471</geo:lat><geo:long>-122.121383</geo:long><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FBradWilson" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FBradWilson" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FBradWilson" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/BradWilson" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FBradWilson" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FBradWilson" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FBradWilson" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare></channel>

<item rdf:about="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt4.html">
<title>Task Parallel Library and Servers, Part 4: TaskHelpers</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/ckQWMrPgrLc/tpl-and-servers-pt4.html</link>
<description>This is part 4 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications. Introduction SynchronizationContext ContinueWith TaskHelpers Simple Task Helpers I know we left off in part 3 with...</description>
<content:encoded><![CDATA[<p><em>This is part 4 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications.</em></p>

<ol>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html">Introduction</a></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt2.html">SynchronizationContext</a></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt3.html">ContinueWith</a></em> </li>
  <li><em><strong>TaskHelpers</strong></em> </li>
</ol>

<h3>Simple Task Helpers</h3>

<p>I know we left off in part 3 with a problem, but we're not going to solve it yet, because we still need to build some foundation helper classes that will make it easier to do that. In particular, there are some good practices we can codify around the creation and conversion of tasks that led us to write the TaskHelpers class that we use today in <a href="http://aspnetwebstack.codeplex.com/">ASP.NET Web Stack</a>.</p>



<h3>Caching Tasks (and Disposability)</h3>

<p>One of the important things to remember about <code>TaskCompletionSource</code> is that it can be somewhat expensive to create. If you look at the implementation of the <code>async</code>/<code>await</code> compiler feature, you'll see that they go to great lengths to cache a bunch of reusable tasks; we don't go quite as far, but we have at least centralized our creation of completed, canceled, and faulted tasks so that we can improve this caching logic as time goes on, as we see fit.</p>

<p>You might've noticed that the <code>Task</code> class implements <code>IDisposable</code>; doesn't that mean you should dispose it when you're done with it? Wouldn't that invalidate all this caching work? It turns out the answer is not so simple; the truth is that it's often impossible to know who the true owner of a task is. Stephen Toub, the architect behind the Task Parallel Library, argues that <a href="http://blogs.msdn.com/b/pfxteam/archive/2012/03/25/10287435.aspx">you should not dispose your <code>Task</code> objects</a>, and his work with the compiler team to enable their caching behavior in .NET 4.5 is the ultimate validation of this argument. Resist the temptation: do not dispose your <code>Task</code>!</p>

<h3>Canceled Tasks</h3>

<p>The first and easiest helpers to show are for the creation of canceled tasks. These are also the easiest thing to cache, since they have no state, so we also get to show how caching might work for the more complex versions.</p>

<pre class="brush:csharp">public static class TaskHelpers
{
    public static Task Canceled()
    {
        return CancelCache&lt;AsyncVoid&gt;.Canceled;
    }

    public static Task&lt;TResult&gt; Canceled&lt;TResult&gt;()
    {
        return CancelCache&lt;TResult&gt;.Canceled;
    }
}

static class CancelCache&lt;TResult&gt;
{
    public static readonly Task&lt;TResult&gt; Canceled
        = GetCancelledTask();

    static Task&lt;TResult&gt; GetCancelledTask()
    {
        var tcs = new TaskCompletionSource&lt;TResult&gt;();
        tcs.SetCanceled();
        return tcs.Task;
    }
}

struct AsyncVoid { }</pre>

<p>We are taking advantage of the static initialization facilities of the C# language, combined with generics, to get a create-on-demand, cached-for-app-lifetime canceled task.</p>

<p>You'll notice that I'm using a private struct (<code>AsyncVoid</code>) as a stand-in to represent the <code>T</code> for our cancel cache. We could have just as easily used any other type, but my feeling here is that it should be trivial to look at some <code>Task</code> object which is-a <code>Task&lt;T&gt;</code> and know whether it was purposefully or accidentally casted down to <code>Task</code>. Perhaps just as importantly, there is no non-generic version of <code>TaskCompletionSource</code>, so not having the result be a <code>Task&lt;T&gt;</code> was kind of out of the question.</p>

<h3>Completed Tasks</h3>

<p>Our next task creation helper is around completed tasks. Here, we do a small amount of caching for completed <code>Task</code>, as well as a completed <code>Task&lt;object&gt;</code> which returns null. The compiler in .NET 4.5 is much more aggresive about pre-computing and caching completed tasks with common return values; we could do the same thing at some point in the future if we so desired, since we funnel all our helpers through here.</p>

<pre class="brush:csharp">public static class TaskHelpers
{
    static readonly Task&lt;object&gt; _completedTaskReturningNull
        = FromResult&lt;object&gt;(null);

    static readonly Task _defaultCompleted
        = FromResult&lt;AsyncVoid&gt;(default(AsyncVoid));

    public static Task Completed()
    {
        return _defaultCompleted;
    }

    public static Task&lt;TResult&gt; FromResult&lt;TResult&gt;(
        TResult result)
    {
        var tcs = new TaskCompletionSource&lt;TResult&gt;();
        tcs.SetResult(result);
        return tcs.Task;
    }

    public static Task&lt;object&gt; NullResult()
    {
        return _completedTaskReturningNull;
    }
}</pre>

<h3>Faulted Tasks</h3>

<p>The final kind of task creation we need to support is faulted tasks. There is really no opportunity for caching here, since the exception objects will be different every time. Note that there are two versions here, one which takes a single exception and one which takes many exceptions; the latter is useful when you're aggregating the results of several faulted tasks together.</p>

<pre class="brush:csharp">public static class TaskHelpers
{
    public static Task FromError(
        Exception exception)
    {
        return FromError&lt;AsyncVoid&gt;(exception);
    }

    public static Task&lt;TResult&gt; FromError&lt;TResult&gt;(
        Exception exception)
    {
        var tcs = new TaskCompletionSource&lt;TResult&gt;();
        tcs.SetException(exception);
        return tcs.Task;
    }

    public static Task FromErrors(
        IEnumerable&lt;Exception&gt; exceptions)
    {
        return FromErrors&lt;AsyncVoid&gt;(exceptions);
    }

    public static Task&lt;TResult&gt; FromErrors&lt;TResult&gt;(
        IEnumerable&lt;Exception&gt; exceptions)
    {
        var tcs = new TaskCompletionSource&lt;TResult&gt;();
        tcs.SetException(exceptions);
        return tcs.Task;
    }
}</pre>

<h3>Run Synchronously</h3>

<p>Calling <code>Task.Factory.StartNew</code> when you don't actually need to do anything asynchronously can be expensively wasteful, because it's likely to spin up a worker thread and cause a thread switch to run your inherently synchronously code. We have several overloads of <code>RunSynchronously</code> which can be used to get <code>Task</code> objects which are already completed and contain the result of the synchronous code. These functions also accept cancellation tokens, and return canceled tasks when the token is signaled; they also take advantage of our previous helper methods to get caching benefits.</p>

<pre class="brush:csharp">public static class TaskHelpers
{
    public static Task RunSynchronously(
        Action action,
        CancellationToken token = default(CancellationToken))
    {
        if (token.IsCancellationRequested)
            return Canceled();

        try
        {
            action();
            return Completed();
        }
        catch (Exception e)
        {
            return FromError(e);
        }
    }

    public static Task&lt;TResult&gt; RunSynchronously&lt;TResult&gt;(
        Func&lt;TResult&gt; func,
        CancellationToken token = default(CancellationToken))
    {
        if (token.IsCancellationRequested)
            return Canceled&lt;TResult&gt;();

        try
        {
            return FromResult(func());
        }
        catch (Exception e)
        {
            return FromError&lt;TResult&gt;(e);
        }
    }

    public static Task&lt;TResult&gt; RunSynchronously&lt;TResult&gt;(
        Func&lt;Task&lt;TResult&gt;&gt; func,
        CancellationToken token = default(CancellationToken))
    {
        if (token.IsCancellationRequested)
            return Canceled&lt;TResult&gt;();

        try
        {
            return func();
        }
        catch (Exception e)
        {
            return FromError&lt;TResult&gt;(e);
        }
    }
}</pre>

<h3>Copying Task Results to TaskCompletionSource</h3>

<p>The final bit of helpers for this post are a few extension methods for <code>TaskCompletionSource</code> which can be used to partially or fully copy the results of a task onto the completion source. These helpers only set the results if the task is currently complete; they don't wait for the task to complete if it has not already done so.</p>

<pre class="brush:csharp">public static class TaskHelpers
{
    public static bool TrySetFromTask&lt;TResult&gt;(
        this TaskCompletionSource&lt;TResult&gt; tcs,
        Task source)
    {
        if (source.Status == TaskStatus.Canceled)
            return tcs.TrySetCanceled();

        if (source.Status == TaskStatus.Faulted)
            return tcs.TrySetException(
                source.Exception.InnerExceptions);

        if (source.Status == TaskStatus.RanToCompletion)
        {
            var tr = source as Task&lt;TResult&gt;;
            return tcs.TrySetResult(
                tr == null
                    ? default(TResult)
                    : tr.Result);
        }

        return false;
    }

    public static bool TrySetFromTask&lt;TResult&gt;(
        this TaskCompletionSource&lt;Task&lt;TResult&gt;&gt; tcs,
        Task source)
    {
        if (source.Status == TaskStatus.Canceled)
            return tcs.TrySetCanceled();

        if (source.Status == TaskStatus.Faulted)
            return tcs.TrySetException(
                source.Exception.InnerExceptions);

        if (source.Status == TaskStatus.RanToCompletion)
        {
            // Sometimes the source is Task&lt;Task&lt;TResult&gt;&gt;,
            // and sometimes it's Task&lt;TResult&gt;. Handle both.

            var ttr = source as Task&lt;Task&lt;TResult&gt;&gt;;
            if (ttr != null)
                return tcs.TrySetResult(ttr.Result);

            var tr = source as Task&lt;TResult&gt;;
            if (tr != null)
                return tcs.TrySetResult(tr);

            return
                tcs.TrySetResult(
                    FromResult(default(TResult)));
        }

        return false;
    }

    public static bool TrySetIfFailed&lt;TResult&gt;(
        this TaskCompletionSource&lt;TResult&gt; tcs,
        Task source)
    {
        switch (source.Status)
        {
            case TaskStatus.Canceled:
            case TaskStatus.Faulted:
                return tcs.TrySetFromTask(source);
        }

        return false;
    }
}</pre>

<h3>What's Next?</h3>

<p>We've got a firm understanding of the fundamentals, and built up all the necessary infrastructure, so now we're ready to start writing our replacement helpers for the existing Task methods; in particular, we will be looking to completely replace the usage of <code>ContinueWith</code> with safer, targeted, a better performing helper methods.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=ckQWMrPgrLc:Jg-JW4NmX9g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=ckQWMrPgrLc:Jg-JW4NmX9g:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=ckQWMrPgrLc:Jg-JW4NmX9g:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=ckQWMrPgrLc:Jg-JW4NmX9g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=ckQWMrPgrLc:Jg-JW4NmX9g:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/ckQWMrPgrLc" height="1" width="1"/>]]></content:encoded>


<dc:subject>ASP.NET</dc:subject>
<dc:subject>ASP.NET MVC</dc:subject>
<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-04-28T18:18:50-07:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt4.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt3.html">
<title>Task Parallel Library and Servers, Part 3: ContinueWith</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/Z98wFZdce4A/tpl-and-servers-pt3.html</link>
<description>This is part 3 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications. Introduction SynchronizationContext ContinueWith TaskHelpers What ContinueWith Really Does I promised that we had a bug in...</description>
<content:encoded><![CDATA[<p><em>This is part 3 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications.</em></p>

<ol>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html">Introduction</a></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt2.html">SynchronizationContext</a></em> </li>
  <li><em><strong>ContinueWith</strong></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt4.html">TaskHelpers</a></em> </li>
</ol>

<h3>What ContinueWith Really Does</h3>

<p>I promised that we had a bug in our previous code, and we did... sort of. Calling <code>ContinueWith</code> without any special flags will cause your continuation to always run, regardless of the final state of the task. We wrote our continuation under the assumption that the <code>Task</code> had completed successfully, which can lead to some very odd and hard to debug problems. Luckily, in our code, we ended up calling <code>Result</code> on the <code>Task</code> object, which turns around and throws an exception if the task had ended in a faulted or canceled state. But what if we'd had a <code>Task</code> rather than a <code>Task&lt;T&gt;</code>? Or what if we hadn't called <code>Result</code>? In .NET 4, this is considered a fatal error condition, and when the task object got garbage collected, its finalizer would've thrown an exception that takes down your <code>AppDomain</code> because you had an unobserved fault! Definitely not good.</p>



<p>That means that we always need to make sure to check the task's status, and if it's faulted, make sure we access the <code>Error</code> property of the task object so that it knows we observed the fault. That's probably a good thing to do, even if we know we're going to touch <code>Result</code>, because it means we get to observe the exception without causing it to be thrown again, and we definitely want to keep unnecessary exceptions to a minimum.</p>

<h3>Unobserved Faulted Tasks in .NET 4 vs. 4.5</h3>

<p>A quick side-note: this &quot;killing the <code>AppDomain</code> because an unobserved faulted task&quot; behavior is unique to .NET 4; it was removed from .NET 4.5. This is because all <code>Task</code>-based programming in .NET 4 was about explicitly returning a <code>Task</code> object. When the team added the <code>async</code> and <code>await</code> keywords to .NET 4.5, they also enabled async methods to return <code>void</code>. They discovered that there was a very useful place for <code>void</code>-returning async methods: as event handlers in UI applications. Since the method returns <code>void</code>, there's no way for the caller to know (or care) that the method they called actually spun off async work to be done; as such, it could no longer be the case that unobserved faults should be an application failure.</p>

<p>That said, these event handlers in client UI applications may be good candidates for <code>void</code>-returning async methods; however, you <strong>must never</strong> use such a method in server event handling (for example, when handling a WebForms event) when the client needs to wait for the result. The event handler that calls your callback has no way of knowing that you have some async work to be done and that it should wait for you to finish, so of course the client will get its response before your work is complete.</p>

<h3>Performance Optimizations</h3>

<p>One more thing we can do with our continuation work is to avoid calling <code>ContinueWith</code> at all. This has two potential benefits:</p>

<ol>
  <li>We can avoid the potential thread hop that comes with <code>ContinueWith</code>; </li>
  <li>We can avoid allocating an extra <code>Task</code> object when not needed. </li>
</ol>

<p>Both of these reasons are good reasons why we should consider helpers for <code>ContinueWith</code> when running on servers.</p>

<h3>Revising Our ContinueWith Example</h3>

<p>Let's start with our example from part 2:</p>

<pre class="brush:csharp">var ctxt = SynchronizationContext.Current;

return SomeThingReturningATask()
      .ContinueWith(innerTask =&gt;
{
    var tcs = new TaskCompletionSource&lt;int&gt;();

    try
    {
        if (ctxt != null)
        {
            ctxt.Post(state =&gt;
            {
                try
                {
                    int result = innerTask.Result;
                    tcs.TrySetResult(result);
                }
                catch(Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            }, state: null);
        }
        else
        {
            int result = innerTask.Result;
            tcs.TrySetResult(result);
        }
    }
    catch(Exception ex)
    {
        tcs.TrySetException(ex);
    }

    return tcs.Task;
});</pre>

<p>Let's extract a helper function out of this:</p>

<pre class="brush:csharp">static Task&lt;TOut&gt; Continue(
        this Task&lt;TIn&gt; task,
        Func&lt;Task&lt;TIn&gt;, TOut&gt; next)
{
    var tcs = new TaskCompletionSource&lt;TOut&gt;();
    var ctxt = SynchronizationContext.Current;

    task.ContinueWith(innerTask =&gt;
    {
        try
        {
            if (ctxt != null)
            {
                ctxt.Post(state =&gt;
                {
                    try
                    {
                        var res = next(innerTask);
                        tcs.TrySetResult(res);
                    }
                    catch(Exception ex)
                    {
                        tcs.TrySetException(ex);
                    }
                }, state: null);
            }
            else
            {
                var res = next(innerTask);
                tcs.TrySetResult(res);
            }
        }
        catch(Exception ex)
        {
            tcs.TrySetException(ex);
        }
    });

    return tcs.Task;
}</pre>

<p>This is the same code as we had above, but now we just call this with a very simple lambda, and all the work is done on our behalf:</p>

<pre class="brush:csharp">return SomeThingReturningATask()
      .Continue(innerTask =&gt; innerTask.Result * 42);</pre>

<p>The helper is taking care of the transition to the sync context automatically for us. Now as we add new capabilities to this helper function, we reap the benefits everywhere we're using it.</p>

<h3>Removing ContinueWith</h3>

<p>The next optimization we want to do is remove the call to <code>ContinueWith</code> entirely if the task we've been given is already completed. This prevents us from hopping onto a new thread to get the work done. In a stack like Web API which has been designed from top to bottom to be async, it turns out that most everything we do completes synchronously, because on the server there are very few reasons to actually wait (remember, we know that we shouldn't thread-hop just to compute something, so our opportunities for async on a server are usually around long-running I/O operations).</p>

<p>If we re-work our example to avoid unnecessary calls to <code>ContinueWith</code>, then it might look something like this:</p>

<pre class="brush:csharp">static Task&lt;TOut&gt; Continue(
        this Task&lt;TIn&gt; task,
        Func&lt;Task&lt;TIn&gt;, TOut&gt; next)
{
    var tcs = new TaskCompletionSource&lt;TOut&gt;();
    var ctxt = SynchronizationContext.Current;

    if (task.IsCompleted)
    {
        try
        {
            var res = next(innerTask);
            tcs.TrySetResult(res);
        }
        catch(Exception ex)
        {
            tcs.TrySetException(ex);
        }
    }
    else
    {
        task.ContinueWith(innerTask =&gt;
        {
            try
            {
                if (ctxt != null)
                {
                    ctxt.Post(state =&gt;
                    {
                        try
                        {
                            var res = next(innerTask);
                            tcs.TrySetResult(res);
                        }
                        catch(Exception ex)
                        {
                            tcs.TrySetException(ex);
                        }
                    }, state: null);
                }
                else
                {
                    var res = next(innerTask);
                    tcs.TrySetResult(res);
                }
            }
            catch(Exception ex)
            {
                tcs.TrySetException(ex);
            }
        });
    }

    return tcs.Task;
}</pre>

<p>In our <code>task.IsCompleted</code> block, notice that I don't bother with the sync context. That's because we're staying on the same thread, so the sync context will be the same. We also have three potential threads of execution in here (the main function body, plus the two lambdas) so we have three try/catch handlers, converting exceptions into faulted tasks.</p>

<h3>Lambdas and Closures</h3>

<p>There is one final bit of optimization left to be done. Now that we have a block of code which calls <code>ContinueWith</code> and a block of code that doesn't, we should be paying close attention to whether our lambda functions are actually <a href="http://en.wikipedia.org/wiki/Closure_(computer_science)">closures</a>.</p>

<p>A closure is a special kind of lambda that has access to the local variables and parameters of the function that it's inside of, even after that function has exited. If you look closely at our call to <code>ContinueWith</code>, you'll see that we are in fact writing a closure, because we use the <code>next</code> parameter as well as the <code>tcs</code> and <code>ctxt</code> variables inside the lambda. If we were diligent, we could get rid of <code>tcs</code>, but we're stuck with the others.</p>

<p>When the compiler generates a closure, it does so by making a tiny object with the state inside of it. Unfortunately, when the compiler realizes that you've got a closure anywhere in your method, it does all the work up front of allocating the state object, even if you never end up using the closure (and if you have two closures, that state object ends up being a combination of the shared values between both closures). When you see code like this which is only sometimes using a closure, it's common to split it up into the non-closure part vs. the closure part.</p>

<p>Let's iterate one more time on the helper function:</p>

<pre class="brush:csharp">static Task&lt;TOut&gt; Continue(
        this Task&lt;TIn&gt; task,
        Func&lt;Task&lt;TIn&gt;, TOut&gt; next)
{
    if (task.IsCompleted)
    {
        var tcs = new TaskCompletionSource&lt;TOut&gt;();

        try
        {
            var res = next(innerTask);
            tcs.TrySetResult(res);
        }
        catch(Exception ex)
        {
            tcs.TrySetException(ex);
        }

        return tcs.Task;
    }

    return ContinueClosure(task, next);
}

static Task&lt;TOut&gt; ContinueClosure(
        Task&lt;TIn&gt; task,
        Func&lt;Task&lt;TIn&gt;, TOut&gt; next)
{
    var ctxt = SynchronizationContext.Current;

    return task.ContinueWith(innerTask =&gt;
    {
        var tcs = new TaskCompletionSource&lt;TOut&gt;();

        try
        {
            if (ctxt != null)
            {
                ctxt.Post(state =&gt;
                {
                    try
                    {
                        var res = next(innerTask);
                        tcs.TrySetResult(res);
                    }
                    catch(Exception ex)
                    {
                        tcs.TrySetException(ex);
                    }
                }, state: null);
            }
            else
            {
                var res = next(innerTask);
                tcs.TrySetResult(res);
            }
        }
        catch(Exception ex)
        {
            tcs.TrySetException(ex);
        }

        return tcs.Task;
    }).Unwrap();
}</pre>

<p>We've split the work into two functions, and we've moved the allocation of the <code>TaskCompletionSource</code> inside the closure. We still have <code>next</code> and <code>ctxt</code> in the closure, but there's nothing we can do about that since there's no way to pass a 'state' object into <code>ContinueWith</code> in .NET 4. Since we moved the TCS into closure, now the <code>ContinueWith</code> call ends up returning a <code>Task&lt;Task&lt;TOut&gt;&gt;</code>, so we use the <code><a href="http://msdn.microsoft.com/en-us/library/dd780917.aspx">Unwrap</a></code> extension method, whose job is to shed that outer <code>Task</code>.</p>

<h3>Unobserved Faulted Tasks</h3>

<p>I started this blog post talking about the bug with unobserved faulted tasks, but... I didn't actually fix that problem. We still need to be sure to observe <code>innerTask.Result</code> so that any faulted task can re-throw its exception appropriately, and we won't end up with a task whose errors weren't observed bringing down our <code>AppDomain</code>. In addition, it seems silly for us to throw exceptions by observing a faulted task just so that it can be turned back into another faulted task, so we'll see if we can deal with that, too.</p>

<p>In the next post in the series, I'll talk about splitting out this one helper method into several optimized methods for each specific scenario (successful results, faulted results, and cancelation), which will also cure of us needing to observe properties on the <code>Task</code> object just to ensure we don't crash later.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=Z98wFZdce4A:Q-6Bi9v7_v0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=Z98wFZdce4A:Q-6Bi9v7_v0:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=Z98wFZdce4A:Q-6Bi9v7_v0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=Z98wFZdce4A:Q-6Bi9v7_v0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=Z98wFZdce4A:Q-6Bi9v7_v0:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/Z98wFZdce4A" height="1" width="1"/>]]></content:encoded>


<dc:subject>ASP.NET</dc:subject>
<dc:subject>ASP.NET MVC</dc:subject>
<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-04-12T17:04:42-07:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt3.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt2.html">
<title>Task Parallel Library and Servers, Part 2: SynchronizationContext</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/4eedat2EEAk/tpl-and-servers-pt2.html</link>
<description>This is part 2 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications. Introduction SynchronizationContext ContinueWith TaskHelpers Introduction to SynchronizationContext An important part of the work in properly handling...</description>
<content:encoded><![CDATA[<p><em>This is part 2 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications.</em></p>

<ol>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html">Introduction</a></em> </li>
  <li><em><strong>SynchronizationContext</strong></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt3.html">ContinueWith</a></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt4.html">TaskHelpers</a></em> </li>
</ol>

<h3>Introduction to SynchronizationContext</h3>

<p>An important part of the work in properly handling tasks on the server is supporting the synchronization context. When you’re using .NET 4.5, then the <code>await</code> keyword automatically does this for you. When you’re consuming <code><a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx">Task</a></code> objects on .NET 4, though, getting yourself back onto the right synchronization context is critical; otherwise, you may cause errors in your application when trying to access things which touch the <code><a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx">HttpContext</a></code> in ASP.NET.</p>



<p>If you’re using <code><a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task_methods.aspx">ContinueWith</a></code> to provide a continuation to run when the task is finished, then you’ll want to stash the <code><a href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx">SynchronizationContext</a></code> and restore when it’s not null. The way you get back onto the right sync context is by calling <code><a href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.post.aspx">Post</a></code>, which is itself an async method…but it’s an async method that returns void, not a <code>Task</code>. The problem is, we’re going to want to return a task that doesn’t finish until everything is done running in the <code>Post</code> callback. How can we do that without a <code>Task</code>?</p>

<p><em><strong>To be clear, there is nothing Task-specific about sync contexts.</strong> They've been with us since .NET 2.0, and if you ever did async/threaded work in ASP.NET (or anything else which has a sync context, like WinForms or WPF), you've always had to respect it. This is one the great things about <code>await</code> in .NET 4.5: it means you can more or less just forget about this, because the compiler is writing all the boilerplate code that I'm about to show you.</em></p>

<h3>TaskCompletionSource: Bridging non-Task async to Tasks</h3>

<p>The <code><a href="http://msdn.microsoft.com/en-us/library/dd449174.aspx">TaskCompletionSource</a></code> class is an interesting beast. It’s an implementation of the task pattern whose task doesn’t mark itself as signaled until you call one of the methods that records whether the task is completed successfully, failed from an exception, or canceled.</p>

<p>As an example of how this works, let’s say you’re calling an &quot;old school&quot; .NET async API that uses the Async/Completed pattern (meaning, it uses events to signal when things are done), and you needed to convert this into a task. Your method might look like this:</p>

<pre class="brush:csharp">public Task&lt;int&gt; SuperAccurateButSlowAdd(int x, int y)
{
    asyncCalculator.Completed += (src, evt) =&gt;
    {
        int result = evt.Result;
        // But now what do I do with it?
    };

    asyncCalculator.AddAsync(x, y);
    // And what do I return here?
}</pre>

<p>The solution to both of the problems above is to use <code>TaskCompletionSource</code>.</p>

<pre class="brush:csharp">public Task&lt;int&gt; SuperAccurateButSlowAdd(int x, int y)
{
    var tcs = new TaskCompletionSource&lt;int&gt;();

    asyncCalculator.Completed += (src, evt) =&gt;
    {
        int result = evt.Result;
        tcs.SetResult(result);
    };

    asyncCalculator.AddAsync(x, y);
    return tcs.Task;
}</pre>

<p>One of the contracts for methods which return <code>Task</code> or <code>Task&lt;T&gt;</code> is that they should only throw exceptions if there was a problem with one of the parameters; otherwise, if they encounter an error in normal execution flow, then they should return a faulted task. So with error handling in both places that could throw, now our code looks like this:</p>

<pre class="brush:csharp">public Task&lt;int&gt; SuperAccurateButSlowAdd(int x, int y)
{
    var tcs = new TaskCompletionSource&lt;int&gt;();

    try
    {
        asyncCalculator.Completed += (src, evt) =&gt;
        {
            try
            {
                int result = evt.Result;
                tcs.TrySetResult(result);
            }
            catch(Exception ex)
            {
                tcs.TrySetException(ex);
            }
        };

        asyncCalculator.AddAsync(x, y);
    }
    catch (Exception ex)
    {
        tcs.TrySetException(ex);
    }

    return tcs.Task;
}</pre>

<p>Since you asked, yes, we do need both of those try/catch blocks. Although it's not clear at first glance, there are actually two functions in here: the main body of <code>SuperAccurateButSlowAdd</code>, and the lambda (anonymous function) that we've wired up to the <code>Completed</code> event. Of course, if you know neither one of those things can throw, then you can remove the try/catch, but you better be positive, because in some cases you could end up in a permanent waiting state.</p>

<p>If you're thinking this code is ripe for &quot;helper methods&quot;, you're right. You're going to see that our <code>Task</code> helper methods are really about reducing the code duplication to a single place, and wrapping things up with nice unit tests to boot.</p>

<h3>Using TaskCompletionSource so we can call SynchronizationContext.Post</h3>

<p>Now that we know how to adapt something which isn't <code>Task</code> into something which is, this is what our code looks like when we want to do a <code>ContinueWith</code> and get back on the proper sync context:</p>

<pre class="brush:csharp">var ctxt = SynchronizationContext.Current;

return SomeThingReturningATask()
      .ContinueWith(innerTask =&gt;
{
    var tcs = new TaskCompletionSource&lt;int&gt;();

    try
    {
        if (ctxt != null)
        {
            ctxt.Post(state =&gt;
            {
                try
                {
                    int result = innerTask.Result;
                    tcs.TrySetResult(result);
                }
                catch(Exception ex)
                {
                    tcs.TrySetException(ex);
                }
            }, state: null);
        }
        else
        {
            int result = innerTask.Result;
            tcs.TrySetResult(result);
        }
    }
    catch(Exception ex)
    {
        tcs.TrySetException(ex);
    }

    return tcs.Task;
});</pre>

<p>Wow, look at all that duplication! :( And it's getting pretty hard to see our code for the noise. We're definitely going to want a helper here. And what's worse is that our code has a bug, and now it's hard to see what it is.</p>

<p>The next blog post will talk about what that missing code might be.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=4eedat2EEAk:NxgbpSOxG_k:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=4eedat2EEAk:NxgbpSOxG_k:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=4eedat2EEAk:NxgbpSOxG_k:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=4eedat2EEAk:NxgbpSOxG_k:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=4eedat2EEAk:NxgbpSOxG_k:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/4eedat2EEAk" height="1" width="1"/>]]></content:encoded>


<dc:subject>ASP.NET</dc:subject>
<dc:subject>ASP.NET MVC</dc:subject>
<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-04-10T18:38:44-07:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt2.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html">
<title>Task Parallel Library and Servers, Part 1: Introduction</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/qfgarMRX_4Y/tpl-and-servers-pt1.html</link>
<description>This is part 1 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications. Introduction SynchronizationContext ContinueWith TaskHelpers Okay, let’s just get this out of the way: Asynchronous (multi-threaded) programming...</description>
<content:encoded><![CDATA[<p><em>This is part 1 in a series on using Task Parallel Library when writing server applications, especially ASP.NET MVC and ASP.NET Web API applications.</em></p>

<ol>
  <li><em><strong>Introduction</strong></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt2.html">SynchronizationContext</a></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt3.html">ContinueWith</a></em> </li>
  <li><em><a href="http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt4.html">TaskHelpers</a></em> </li>
</ol>

<p>Okay, let’s just get this out of the way:</p>
<p><strong>Asynchronous (multi-threaded) programming is not easy.</strong></p>
<p>This warning really has nothing to do with .NET in particular, because it can be quite challenging to do correctly on any framework, but here’s the good news:</p>
<p><strong>Asynchronous programming with .NET 4 is a little easier.      <br />Asynchronous programming with .NET 4.5 is a lot easier.</strong></p>
<p>

</p>
<p>The Task Parallel Library (or, as we think about it, <code>Task</code> and <code>Task&lt;T&gt;</code>) were introduced in .NET 4. This library dramatically simplified the more complex async patterns from previous versions of .NET (which includes the begin/end pattern as well as the async/completed event pattern).</p>
<p>The <code>async</code> and <code>await</code> keywords available in C# and VB on .NET 4.5 mean you get to consume Task Parallel Library tasks with code that looks linear and synchronous, but is in actuality asynchronous, with none of the callback handlers or thread synchronization stuff getting in the way. For most developers, this means that asynchrony is simple enough to consume without too much trouble; in fact, the Windows team is so confident of this that all the APIs for modern apps in Windows 8 that might “take a while” (read: more than 100ms) are required to be async, with no synchronous counterpart. The Windows team did this so that you won’t inadvertently lock up the UI and cause the app to appear to be unresponsive, although of course you could end up doing this by running some long running process in your own code on the UI thread.</p>
<p>As such, a great deal of the samples for 4.5 using <code>Task&lt;T&gt;</code> are centered around pushing “long running” tasks onto a background thread so you don’t lock up the UI. There are also a decent number of samples that show using the TPL for parallel processing: that is, when you have something which is CPU-bound, and can be split up into discrete tasks, you run many of them in parallel so as to get the best use of modern multi-core CPUs.</p>
<p>There is another category of asynchronous programming, though, that has had very little ink devoted to it: server-side programming; in particular, using <code>Task&lt;T&gt;</code> when writing web applications and web APIs, which yields the real purpose for this blog post:</p>
<p><strong>Asynchronous programming for servers is not the same as clients.</strong></p>
<p>Client asynchrony is all about getting work off the all-important UI thread, so that the UI appears to be response to the user, even when working is going on in the background. On a server, there is no such thing as a background thread vs. a UI thread: <em>every thread in the thread pool is a potential handler for a request, and the client has to wait until all the work is done, regardless of which thread(s) it takes place on.</em></p>
<p>In the context of servers, the most important thing to remember is that we don’t want to switch threads if at all possible, because a thread context switch can dramatically reduce the scalability of your server. That means whenever you consume a task, you have to be careful to use mechanisms that don’t switch the thread unnecessarily.</p>
<p>In addition, there’s no point in making a task on the server when what you’re doing is fundamentally CPU-bound. There’s no background thread for this work to hide on, so all you’re doing is incurring an expensive thread switch. Where TPL makes sense on servers is when you’re consuming something which is fundamentally async but not CPU bound, which means things like database operations and web service calls.</p>
<p>A final consideration for your server-based TPL code is <em>synchronization contexts</em>. The <code>SynchronizationContext</code> class was introduced in .NET 2.0 as an abstraction around the need for asynchronous code to get its state lined back up to continue correctly functioning. In the case of Windows Forms and WPF, this means ensuring that your post-async code is running on the UI thread so that you can do UI manipulation; in the case of ASP.NET, this means ensuring that your current thread has all the necessary thread-local statics set up (so that calls like <code>HttpContext.Current</code> function correctly).</p>
<p>Further blog posts in this series will talk about how to safely consume Tasks from your server code on .NET 4, and some rather in-depth analysis of the task helper libraries that the ASP.NET team has made to ensure that Task-related code runs in the way that incurs the least amount of performance impact.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=qfgarMRX_4Y:Qwk5xSwKLko:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=qfgarMRX_4Y:Qwk5xSwKLko:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=qfgarMRX_4Y:Qwk5xSwKLko:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=qfgarMRX_4Y:Qwk5xSwKLko:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=qfgarMRX_4Y:Qwk5xSwKLko:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/qfgarMRX_4Y" height="1" width="1"/>]]></content:encoded>


<dc:subject>ASP.NET</dc:subject>
<dc:subject>ASP.NET MVC</dc:subject>
<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-04-10T12:40:25-07:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/04/tpl-and-servers-pt1.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2012/04/xunit-moving-to-git.html">
<title>xUnit.net Moving to Git</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/N40TCeWZwPo/xunit-moving-to-git.html</link>
<description>Just a quick note: the xUnit.net source control repository is switching from Mercurial to Git on Friday the 13th of April. If you have outstanding forks or pull requests, please read this page for how this change will affect you....</description>
<content:encoded><![CDATA[<p>Just a quick note: the xUnit.net source control repository is switching from Mercurial to Git on Friday the 13th of April. If you have outstanding forks or pull requests, please read this page for how this change will affect you.</p>
<p><a href="http://xunit.codeplex.com/discussions/351482" target="_self">http://xunit.codeplex.com/discussions/351482</a></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=N40TCeWZwPo:R592fjcUmJY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=N40TCeWZwPo:R592fjcUmJY:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=N40TCeWZwPo:R592fjcUmJY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=N40TCeWZwPo:R592fjcUmJY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=N40TCeWZwPo:R592fjcUmJY:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/N40TCeWZwPo" height="1" width="1"/>]]></content:encoded>


<dc:subject>Agile</dc:subject>
<dc:subject>Technical</dc:subject>
<dc:subject>xUnit.net</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-04-08T07:19:03-07:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/04/xunit-moving-to-git.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2012/03/win8-cp-on-ss7s.html">
<title>Windows 8 Consumer Preview on Samsung Series 7 Slate</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/LKI9W5EzbLE/win8-cp-on-ss7s.html</link>
<description>Update #1: Samsung has released Windows 8 drivers to support better touch and rotation with Windows 8. Please go download them now! Update #2: There is a forum post outlining how to get WiDi (wireless display) working in Windows 8....</description>
<content:encoded><![CDATA[<div style="padding: 0.5em 1em; background-color: #eee; margin-bottom: 1em;">
<p><em><strong>Update #1:</strong>&nbsp;Samsung has released&nbsp;<a href="http://www.samsung.com/global/windowspreview/" target="_self">Windows 8 drivers to support better touch and rotation</a>&nbsp;with Windows 8. Please go download them now!</em></p>
<hr />
<p><em><strong>Update #2:</strong> There is a forum post outlining <a href="http://www.eightforums.com/hardware-drivers/5117-intel-widi.html">how to get WiDi (wireless display) working in Windows 8</a>. Since I don't have a WiDi endpoint and thus can't test this, I can't really speak to the&nbsp; effectiveness of the instructions.</em></p>
</div>
<p>This is an update to my <a href="http://bradwilson.typepad.com/blog/2011/11/win8-dp-on-samsung-series-7-slate.html" target="_self">previous post</a> about running Windows 8 Developer Preview on the Samsung Series 7 Slate. Until we get Windows 8 logo'd hardware, I believe this to be the best developer device for doing early explorations into Windows 8 development on.</p>
<p>That said, this is still beta-level software. Tread carefully. :)</p>
<p>

</p>
<h3>Obligatory Warning You Will Probably Ignore</h3>
<p>What you're doing here is erasing a computer. You can screw things up if you do them incorrectly. This worked for me, but it may not work for you. If you get stuck, I may not be able to help you, and Samsung may not be super excited about helping you out with a Windows 8 problem. Also, Windows 8 is pre-release software, so expect some occasional bumps in the road.</p>
<p>Although you can upgrade your existing Windows 7 partition to Windows 8, I'm a big proponent of the "clean slate" mentality, so this blog post was written with that in mind. If you're insistent on doing an upgrade instead, please remember to do the pre-installation steps (0 and 1), because they apply whether you're paving or clean installing. Then in step 2, instead of booting the USB device, just insert it into the USB slot while booted into Windows 7 and it should offer to run setup and do the upgrade for you.</p>
<h3>Important Links:</h3>
<ul>
<li><a href="http://windows.microsoft.com/en-US/windows-8/iso">Windows 8 Consumer Preview Download</a></li>
<li><a href="http://www.intowindows.com/how-to-install-windows-7vista-from-usb-drive-detailed-100-working-guide/" target="_self">Making a bootable USB thumb drive from the Windows 8 ISO</a></li>
<li><a href="http://www.samsung.com/us/support/owners/product/XE700T1A-A04US" target="_self">Samsung Series 7 Slate Software Downloads</a></li>
<li><a href="http://www.samsung.com/global/windowspreview/" target="_self">Samsung Series 7 Slate drivers for Windows 8</a></li>
</ul>
<h3>What You'll Need to Get Started</h3>
<ul>
<li>A bootable USB device to install Windows 8; meaning, either a USB DVD drive or a USB thumb drive. If you want to use the latter, follow the instructions linked above to make the thumb drive properly bootable. You'll want a 4GB+ thumb drive for Windows 8 x64. Your machine has 4GB of RAM, so don't bother with the x86 (32-bit) verison of Windows 8. Installation from a USB thumb drive is a LOT faster than installation from a DVD (and doesn't waste a blank DVD).<br />&nbsp;<br /><strong><em>Pro-Tip: format the USB device as FAT32, not NTFS, if you want to enable UEFI boot (which should speed up your already quite fast booting process on this device). When booting, if offered two different versions of your USB boot device, choose the one with "EFI" in its title.</em></strong><br />&nbsp;</li>
<li>A keyboard and mouse is highly advised for some parts. You can get by without it, but it's... painful. If you're planning to use a USB keyboard, bear in mind that you'll be booting off of a USB drive, so you'll either need a USB hub, or you'll need to use the optional dock to get yourself a 2nd USB port.</li>
</ul>
<h3>Step 0: Update your firmware (before you delete Windows 7!)</h3>
<p>Your machine may have shipped with the latest firmware, but it's worth verifying that to be sure. A relatively new firmware (version 08FW at the time of this writing) is necessary to ensure that TPM and Bitlocker work correctly, and will also be necessary for screen rotation support when the driver becomes available.</p>
<p>Boot into Windows 7. Visit the <a href="http://www.samsung.com/us/support/owners/product/XE700T1A-A04US" target="_self">Series 7 Slate Downloads</a> page, click on the Manuals &amp; Downloads tab, then the Firmware link, and download the firmware updater. Run it to ensure you are on the latest firmware.</p>
<p><em><strong>Note for advanced users:</strong> I created a "boot from VHD" version of Windows 7 for updating my firmware. It "costs" me about 20GB of my drive, which is kinda steep, but it's worth it to have something that allows me to upgrade my firmware whenever there's a new version. Besides Windows 7, all I've installed is the Samsung drivers/software necessary to update the firmware. Once the Samsung tools become fully Windows 8 compatible, then I'll be able to reclaim this. If you need help understanding how to do this, Scott Hanselman's <a href="http://www.hanselman.com/blog/GuideToInstallingAndBootingWindows8DeveloperPreviewOffAVHDVirtualHardDisk.aspx">Guide to Installing and Booting Windows 8 Developer Preview off a VHD</a> illustrates the steps excellently, which work for both Windows 7 and Windows 8.</em></p>
<h3>Step 1: Make some machine settings changes</h3>
<p>With the machine in a powered off state, press the POWER button, then quickly tap (but do not hold) the HOME button. Now be patient, you should see the boot menu (of which one option is to boot into the firmware).&nbsp;<em>Don't get anxious and hit it a second time, because you're almost sure to accidentally escape out of the boot menu; trust me, I think I did this 3x before I learned to be a tiny bit more patient. :)</em></p>
<p>The contents of this menu will vary depending on which boot features you've enabled; for me, they were:</p>
<p><strong>P0: SAMSUNG MZMPA128HMFU-00000</strong>&nbsp;(this is your SSD drive)<br /><strong>SMI USB DISK 1100</strong>&nbsp;(this is my 8GB USB stick that I'm planning to boot from)<br /><strong>Realtek PXE B02 D00</strong>&nbsp;(this is the network boot via Ethernet)<br /><strong>Enter Setup</strong>&nbsp;(this will drop you into the machine settings again)&nbsp;</p>
<p>Attaching a USB keyboard helps navigation here a lot (though you should attach it before you power on the device; I don't think it will detect it if you try to plug it in later). If you don't, then you'll need to use the hardware keys to navigate:</p>
<ul>
<li><strong>Rotation Lock</strong>&nbsp;(on the right, below the power button)- Enter</li>
<li><strong>Home</strong>&nbsp;(the only button on the face of the device) - Escape</li>
<li><strong>Volume Up/Down</strong>&nbsp;(on the left, below the USB port) - Move the cursor up/down</li>
<li><strong>Hold Rotation Lock + Volume Up/Down</strong>&nbsp;- Move the cursor left/right</li>
</ul>
<p>Use the USB keyboard (or the volume up/down keys on the device) to select "Enter Setup", then press Enter (or Rotation Lock on the device).&nbsp;Once in the firmware, the machine settings screen is displayed:</p>
<p><img src="http://bradwilson.typepad.com/samsung-series-7-bios.jpg" border="0" alt="" /></p>
<p>The BIOS changes we want to make/verify are all on the Advanced page:</p>
<ul>
<li><strong>CPU Power Saving Mode</strong> : Enabled</li>
<li><strong>Hyperthreading</strong> : Enabled</li>
<li><strong>Execute Disable Bit</strong> : Enabled</li>
<li><strong>Legacy USB Support</strong> : Enabled</li>
<li><strong>UEFI Boot Support</strong> : Enabled</li>
</ul>
<p>There are two additional interesting settings on the Boot page, which you may or may not want to change:</p>
<ul>
<li><strong>TPM Support&nbsp;</strong>: you'll want to Enable this if you want to use Bitlocker to secure the contents of your slate. Some corporate environments (like mine) require that you use Bitlocker, and TPM means you won't have to carry around an extra USB key with Bitlocker booting codes on it.</li>
<li><strong>PXE OPROM&nbsp;</strong>: you'll want to Enable this if you have the optional dock, and you're planning to install Windows via the network, as network booting requires a physical Ethernet connection. This is probably not useful right now with Windows 8, but you may find it useful if you decide to revert back to Windows 7 at some point (assuming you're on a network with network boot support).</li>
</ul>
<p>Navigate to the Exit page, and choose "Save Changes and Reset". But before you do that, read ahead just one more paragraph.</p>
<h3>Step 2: Boot the USB device to install Windows 8</h3>
<p>When the machine reboots after we save and exit the settings screen, once again we want to tap and release the HOME button once to get to the boot menu. This time, navigate to the USB device that you're booting from and select it. <em>(Remember, if you're not using a USB keyboard, you can use the device keys Volume Up and Volume Down to move, and Rotation Lock to select.)</em></p>
<p>The Windows 8 installation includes enough drivers to do mouse emulation for the slate's touch screen, so I was able to touch my way through the install process. I nuked both the Windows 7 partition and the factory restore partition, because I was confident that I would rather reinstall Windows 7 from scratch anyway. Just bear in mind that your slate didn't come with a Windows 7 DVD (or thumb drive), so unless you have an extra Windows 7 DVD hanging around that's usable for this, you'll want to preserve the factory restore partition. Me, I wanted that extra 20GB back. :)</p>
<p>Since there is no on-screen keyboard, if you want to do any advanced partitioning, you'll basically have to boot with a USB keyboard connected for the installation. Tapping the down arrow on the partition size edit box over and over again gets old REALLY fast. :)</p>
<p>After you've picked your installation partition, the system will do its copy thing and then reboot to finalize the installation. Now Windows 8 is running in full swing, and final settings (like connecting to WiFi and logging in with your Windows Live ID) are touch-friendly operations with on-screen keyboards available.</p>
<p>After your initial logon, you're on the Start Screen. At this point, I'd recommend connecting your Bluetooth keyboard and mouse (if you're using USB, then there's no connection necessary other than just plugging things in). FWIW, the Start Screen is great on this slate, but classic desktop mode can be challenging without a keyboard and mouse. I wouldn't recommend it for anything other than casual usage, and instead limit yourself to the Start Screen (and touch-designed apps) when you don't have a keyboard and mouse.</p>
<p>Alternatively, you can use the provided pen for light mouse-like usage. This slate comes with both a real digitizer as well as touch screen, and it turns off the touch functionality when the pen is nearby, so it's actually quite nice to write with using the provided pen, as you can lean the edge of your hand on the glass to write without triggering any touch operations. Honestly, this is a great slate for people who like to write, and I suspect I'll get a lot more use out of OneNote with this than any previous PC.</p>
<p>Regardless of what kind of precision input device you're using, we're going to make some changes and do some work in classic desktop mode next.</p>
<h3>Step 3: Run Windows Update</h3>
<p>From the Start Screen, swipe in from the right edge, tap Search, and then search for "Windows Update". Tap on the Settings sub-search, and then tap on "Check for updates". This will launch the desktop version of Windows Update. If you're careful with your taps, you might be able to use this app without resorting to a mouse or pen.</p>
<p>Force Windows Update to search for drivers, even if it thinks you're up-to-date. This will end up giving you most of the drivers you're missing. For me, this included nearly 20 updates in total. As is typical with Windows Update, you will probably need to reboot one or more times to get everything updated properly. Continue to install/reboot dance until Windows Update comes up empty.</p>
<h3>Step 4: Install Drivers For Missing Devices</h3>
<p>When you look in Device Manager, you'll probably have two "banged out" devices that are missing drivers. One is the rotation sensor (for which there aren't any drivers yet), and the other is a device that's covered in the Intel Chipset drivers.</p>
<p>Head back to the <a href="http://www.samsung.com/us/support/owners/product/XE700T1A-A04US" target="_self">Series 7 Slate Downloads</a> page. Click on the Manuals &amp; Downloads tab, but this time click on the Driver link, and download the driver named "Chipset". Install this driver and reboot. One of your two mysteryous devices with no driver should have gone away now.</p>
<p><strong>Update:</strong>&nbsp;Samsung has released <a href="http://www.samsung.com/global/windowspreview/" target="_self">Windows 8 drivers to support better touch and rotation</a> with Windows 8. Please go download them now!</p>
<h3>Step 5: There is No Step 5</h3>
<p>That's it! The Consumer Preview version of Windows 8 just continues to make my blissfully happy with my investment in this "developer-quality laptop without a keyboard". It really shines!</p>
<p>Time to enjoy your new Windows 8 slate!</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=LKI9W5EzbLE:d2IoFGAdEiI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=LKI9W5EzbLE:d2IoFGAdEiI:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=LKI9W5EzbLE:d2IoFGAdEiI:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=LKI9W5EzbLE:d2IoFGAdEiI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=LKI9W5EzbLE:d2IoFGAdEiI:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/LKI9W5EzbLE" height="1" width="1"/>]]></content:encoded>


<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-03-06T19:06:36-08:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/03/win8-cp-on-ss7s.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2012/01/xunit19.html">
<title>Shipped: xUnit.net 1.9</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/05dKF2MD-FY/xunit19.html</link>
<description>On January 2nd, Jim and I shipped xUnit.net 1.9. We updated NuGet with the 1.9 build binaries, and for the first time, we're including the MSBuild runner inside the "xunit" NuGet package. There are a few big new features that...</description>
<content:encoded><![CDATA[<p>On January 2nd, <a href="http://jamesnewkirk.typepad.com/">Jim</a> and I shipped <a href="http://xunit.codeplex.com/releases/view/77573">xUnit.net 1.9</a>. We updated NuGet with the 1.9 build binaries, and for the first time, we're including the MSBuild runner inside the <a href="http://nuget.org/packages/xunit">"xunit" NuGet package</a>.</p>
<p>There are a few big new features that are worth calling out.</p>

<h3>Async Unit Tests</h3>
<p>Late in 2010, the C# team announced a new feature that was coming in C# 5: the "async" and "await" keywords. These keywords allow the developer to consume <a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx">Task</a>-based asynchronous APIs with code that looks linear and procedural, and mimics the code that the developer would write when calling synchronous APIs. In addition, .NET 4.5 is introducing new Task-based async APIs to supplement the existing event-based asynchronous APIs, and new async APIs will only offer Task-based versions.</p>
<p>Before now, unit testing these asynchronous APIs meant resorting to calls like .Wait() and .ContinueWith(), since unit testing frameworks are inherently synchronous by nature. With the release of 1.9, xUnit.net allows you to write asynchronous unit tests by marking your test method with the "async" keyword, and changing the return value from void to Task.</p>
<p>Prior to 1.9, a unit test around an asynchronous API might look something like this:</p>
<pre class="brush:csharp">[Fact]
public void MyAsyncUnitTest()
{
    // ... setup code here ...

    Task task = CallMyAsyncApi(...)
               .ContinueWith(innerTask =&gt;
    {
        var result = innerTask.Result;

        // ... assertions here ...
    }

    task.Wait();
}</pre>
<p>The code gets sufficiently more complex with every additional asynchronous API you add into the mix (for example, calling some async APIs during the setup phase of the unit tests). Adding try/catch logic becomes difficult and/or redundant, as the exception handling logic needs to be duplicated for both the setup code and the ContinueWith handler).</p>
<p>The same unit test can be simplified by using xUnit.net 1.9 (and either the Async CTP, or the pre-release version of .NET 4.5 which includes C# 5):</p>
<pre class="brush:csharp">[Fact]
public async Task MyAsyncUnitTest()
{
    // ... setup code here ...

    var result = await CallMyAsyncApi(...);

    // ... assertions here ...
}</pre>
<p>xUnit.net does the rest of the work. It sees that you're returning a Task and waits for it to complete. Traditional sequential coding mechanics like try/catch/finally and using are much easier to reason about when using async/await, and the compiler takes care of the boilerplate code necessary to ensure that it all works properly.</p> 
<h3>Generic Theories</h3>
<p>One of the most used features in the xUnit.net Extensions project is support for theories. In quick review: Facts are for expressing tests which are invariants; Theories are used for expressing tests that are only necessarily true for a given set of input data. As such, theories are sometimes called "data-driven unit tests", because part of testing a theory is providing sets of conforming data.</p>
<p>The new Generic Theories feature allows the developer to write their theories using the .NET generic method syntax. xUnit.net will attempt to determine the best signature for the generic types of the method based on the provided data, and it makes this decision individually on a data-row by data-row basis. This is most useful for writing unit tests against generic APIs, wherein you want to choose the generic API to call based on the type of the input data.</p>
<p>For example, here is a unit test which is testing a generic get-and-cast behavior of a container:</p>
<pre class="brush:csharp">[Theory]
[InlineData(42)]
[InlineData(21.12)]
[InlineData("Hello, world!")]
public void CastingGetTest&lt;T&gt;(T value)
{
    MyContainer container = new MyContainer();
    container.SetValue("name", value);

    T result = container.Get&lt;T&gt;("name");

    Assert.Equal(value, result);
}</pre>
<p>This generic theory will be called 3 times as expected, and the type of T will be implied based on the value that was provided. We've also updated the output from theories to include any generic types that were used, so if this theory fails, its output method names would be:</p>
<pre class="brush:csharp">CastingGetTest&lt;Int32&gt;(value: 42)
CastingGetTest&lt;Double&gt;(value: 21.12)
CastingGetTest&lt;String&gt;(value: "Hello, world!")</pre>
<p>This highlights another new feature of 1.9 as well: theory names include parameter names in addition to parameter values.</p>
<p>The rules for matching are fairly straightforward:</p>
<ul>
<li>If the generic type has no matching parameters, we use Object</li>
<li>If the generic type has one matching parameter:</li>
<ul>
<li>If the parameter value is non-null, we use value's concrete type</li>
<li>If the parameter value is null, we use Object</li>
</ul>
</li>
<li>If the generic type has two or more matching parameters:</li>
<ul>
<li>If the parameters are the <em><strong>exact same</strong></em> concrete type, we use the concrete type <em>(note that a null value is type-compatible with any reference type, but type-incompatible with any value type)</em></li>
<li>If the parameters are not the exact same concrete type, we use Object</li>
</ul>
</ul>
<p>We could've gone with a more complex matching algorithm, but we wanted the results to be easy to understand and reasonably predictable without stashing away dozens of matching rules in your head.</p>
<p><em>An important note: this support is limited to generic test methods only. xUnit.net does not support generic test classes.</em></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=05dKF2MD-FY:8wYrYWn-tq0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=05dKF2MD-FY:8wYrYWn-tq0:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=05dKF2MD-FY:8wYrYWn-tq0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=05dKF2MD-FY:8wYrYWn-tq0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=05dKF2MD-FY:8wYrYWn-tq0:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/05dKF2MD-FY" height="1" width="1"/>]]></content:encoded>


<dc:subject>Agile</dc:subject>
<dc:subject>Technical</dc:subject>
<dc:subject>xUnit.net</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2012-01-25T08:39:08-08:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2012/01/xunit19.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2011/12/best-music-of-2011.html">
<title>Best Music of 2011</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/Ow6Dxx0bJnw/best-music-of-2011.html</link>
<description>Time for the annual "best of" blog post, and this year was packed full of more great music than I can ever remember. I flirted with buying my music only online this year, but have since switched back to CDs,...</description>
<content:encoded><![CDATA[<p>Time for the annual "best of" blog post, and this year was packed full of more great music than I can ever remember.</p>

<p>I flirted with buying my music only online this year, but have since switched back to CDs, so that I can rip everything in lossless. Automatic downconversion to the phone is great, and I can still keep my lossless audio streams for the house, and all it costs is disk space (for my complete music collection, that's roughly 1TB). This is also the year I dumped my Zune Pass, and tried (but failed to be captivated by) Spotify.</p>

<p><em>Previous years: <a href="http://bradwilson.typepad.com/blog/2010/12/best-music-of-2010.html" target="_self">2010</a>,&nbsp;<a href="http://bradwilson.typepad.com/blog/2009/12/music-of-2009.html">2009</a>,&nbsp;<a href="http://bradwilson.typepad.com/blog/2008/12/music-of-2008.html">2008</a>,&nbsp;<a href="http://bradwilson.typepad.com/blog/2007/12/music-of-2007.html">2007</a></em><a href="http://bradwilson.typepad.com/blog/2007/12/music-of-2007.html"></a></p>



<h2>Genre: Alternative</h2>

<h3>R.E.M. — Collapse into Now</h3>

<p>2011 is the year that R.E.M. released its first truly great album in probably a decade... and then promptly broke up. Good jorb, guys.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/SRR1a4LAdNA?rel=0" frameborder="0"></iframe></p>

<h2>Genre: Metal</h2>

<h3>Anthrax — Worship Music</h3>

<p>Against all odds, Anthrax is back, and with Joey back at lead vocals. Worship Music is a great throwback to the classic 'thrax of olden days.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/HvdD3gBmUtQ?rel=0" frameborder="0"></iframe></p>

<h3>Iced Earth — Dystopia</h3>

<p>I had more or less written off Iced Earth as being uninteresting. There was the flirtation with Tim "Ripper" Owens that yielded one great album and a bunch of meh. Then they went back to long-time singer Matt Barlow, but he didn't seem to have the heart, and was gone after one album. Now they've found another (their 5th?) in Stu Block, and his vocal style honestly combines the best of Barlow and Ripper, and the music feels emotionally inspired again. Welcome back, guys!</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/zuwW9IVwZ0U?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Mastodon &mdash; The Hunter</h3>

<p>Mastodon's last album was a mixed bag: some thought it was the best of their career, and some thought it the worst. I definitely found myself in the former camp, and I think The Czar remains some of the best stuff they've ever done. This new album is quite good, though not quite up to the standards of the last album. It feels less progressive and more conventional.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/hwgqenxNUfs?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Megadeth &mdash; Th1rt3en</h3>

<p>Megadeth have always been a more consistent band than Metallica for metal fans (Risk notwithstanding), and their 13th studio album still delivers the fire from the old days.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/qHMUyHZi440?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Symphony X &mdash; Iconoclast</h3>

<p>A new SymX disc is always cause for celebration. Russell Allen has one of the greatest voices in metal (now that Dio is no longer with us), and their symphonic/power metal prowess is, as always, honed to a very fine edge.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/7QtLbXeQkV8?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Within Temptation &mdash; The Unforgiven</h3>

<p>I'm a sucker for concept albums and for female metal singers, so this was a double dose for me. It's a little pop-ish for some metal fans' tastes, but Sharon den Andel is always great to listen, because she tends to have a more reserved style than many other female metal singers. The bonus videos with the album were an excellent treat!</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/qGdzgcDllYE?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h2>Genre: Extreme Metal</h2>

<h3>Amon Amarth &mdash; Surtur Rising</h3>

<p>I'm a latecomer to Amon Amarth (and extreme metal in general), so while others didn't really think much of Twilight of the Thunder Gods, I liked it quite a lot. Surtur Rising is superior in pretty much every important way, and is a regular player even many months after its release.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/YFNc9jrkY4I?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Arch Enemy &mdash; Khaos Legions</h3>

<p>Another refinement in the melodic death metal machinery of Arch Enemy... yes, it's different than the old material, but it's pretty great in its own right.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/l7NgiZv3ncc?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Between the Buried and Me &mdash; The Parallax: Hypersleep Dialogues</h3>

<p>Calling this "just a three song EP" downplays the masterful music that spans nearly 30 minutes, almost long enough to be considered an album were this 20 years ago. Just whets the appetite for the next full length album...</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/MxPVyPXKKhU?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>The Black Dahlia Murder &mdash; Ritual</h3>

<p>There isn't a lot of metal coming out of my home town of Detroit these days, but TBDM more than make up for it with some seriously brutal yet brilliantly melodic metal.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/SEjGbxaunNI?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Fleshgod Apocalypse &mdash; Agony</h3>

<p>I'd never heard of these guys before hanging out on Turntable.fm, so imagine my surprise at the unbelievable combination of technical death metal and orchestral arrangements that awaited me. The talent in this band, especially the drummer, is nearly inhuman.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/D2b6jBoSGNw?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Ghost Brigade &mdash; Until Fear No Longer Defines Us</h3>

<p>Listening to this album Every. Single. Day. 'nuff said.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/6kubmMxykI8?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Insomnium &mdash; One for Sorrow</h3>

<p>Insomnium are yet another one of those quiet, competent ass-kicking melodic death metal bands that doesn't ever quite get the recognition it deserves. Another fine outing!</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/Ns9_A3CKqPM?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Obscura &mdash; Omnivium</h3>

<p>Ever since Metallica started opening their albums with acoustic, classical-inspired snippets, I've had a fondness for the unexpected during those first 60 seconds of the album. Obscura bat it out of the park with this opener!</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/snDfSqcPHWk?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Omnium Gatherum &mdash; New World Shadows</h3>

<p>This is my first album from the Finnish melodic death metal band, but it definitely won't be my last. Soul Journey is probably one of the best melodeath songs of the year.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/42qbzF_ektM?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Opeth &mdash; Heritage</h3>

<p>Mikael disappointed a lot of long-time fans when he announced that Opeth's newest album would not only be all clean vocals, but a rather stark musical departure at that. More inspired by 70's fusion jazz and progressive rock than modern metal, it really hits a sweet spot for me. The whole album is audible candy.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/FxvN_GxgpF8?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Scar Symmetry &mdash; The Unseen Empire</h3>

<p>When Christian left Scar Symmetry, many fans were shocked that they replaced him with not one but two vocalists. Although both can sing and growl, each has their stronger suits. The resulting first album was Dark Matter Dimensions, and most long-time fans thought it was probably the end of old SS. The Unseen Empire proved that they just need to get back on creative track.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/ArELZEYr444?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h2>Genre: Progressive Rock/Metal</h2>

<h3>Andromeda &mdash; Manifest Tyranny</h3>

<p>I've always been a pretty big fan of Andromeda's mix of prog metal and futuristic sounds and topics. This new album definitely steps up the pace quite a bit at times, especially the opening track.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/uiSaakTpZ-o?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Arch/Matheos &mdash; Sympathetic Resonance</h3>

<p>This is probably metal heresy, but there's something very Queensryche-ian about Arch/Matheos, which is to say that it reminds of the glimpse of the greatness that Operation: Mindcrime convinced us Queensryche had inside, but couldn't quite deliver on reliably. Arch/Matheos have no such problems.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/IwcL04CYews?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Dream Theater &mdash; A Dramatic Turn of Events</h3>

<p>With no small amount of irony did Dream Theater choose the name of their latest album. This year saw the band lose one of its founding members (and musical backbone) in Mike Portnoy. DT decided to keep moving forward and hired Mike Mangini, and turned the audition and hiring process into a three part YouTube series. Just as importantly, they created some of the most solid material in more than a decade.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/usPqh66pQaA?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Evergrey &mdash; Glorious Collision</h3>

<p>Evergrey are like the Little Prog Metal Band That Could. They keep soldiering on in undeserved obscurity, turning out album after album of incredibly solid music.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/DQcJuzMwGc0?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Protest the Hero &mdash; Scurrilous</h3>

<p>This is PtH's most commercially acceptable release, which is still a long damn way from what other bands might call "selling out". The undertone of crazy is still here, though.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/vKZ-eKBJ9dw?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Steven Wilson &mdash; Grace for Drowning</h3>

<p>Steven Wilson is the brains behind Porcupine Tree, and a long-time musical collaborator with Mikael and the boys in Opeth. His solo work tends to be more experimental and atmospheric than Porcupine Tree.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/dte3-sSkWic?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>TesseracT &mdash; One</h3>

<p>One of the most refined and unique sounds in progressive metal today, TesseracT were an obvious immediate addiction to me.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/JF_YIiRoRFM?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Textures &mdash; Dualism</h3>

<p>Textures blends a bit of progressive metal, and occasional metalcore and djent tendencies.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/mcIliX_z_7M?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h2>Genre: Soundtrack</h2>

<h3>The Girl With the Dragon Tattoo</h3>

<p>Trent Reznor seems to have diverted his career into soundtracks, and with great success. Last year his big success was The Social Network; this year, he succeeds well with The Girl With the Dragon Tattoo. The opening credits have this quite good cover of Led Zeppelin serving as the audio backdrop.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/ljbBayiWglg?rel=0" frameborder="0" allowfullscreen></iframe></p>

<h3>Tron: Legacy Reconfigured</h3>

<p>Technically, the original soundtrack came out last year with the movie, but there was a remix CD released this year. The most shocking thing about it is how much better it is than the original, which I would've said was one of the best soundtracks released in many years.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/fMd3u5fEouo?rel=0" frameborder="0" allowfullscreen></iframe></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=Ow6Dxx0bJnw:o0R6T8WOMG8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=Ow6Dxx0bJnw:o0R6T8WOMG8:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=Ow6Dxx0bJnw:o0R6T8WOMG8:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=Ow6Dxx0bJnw:o0R6T8WOMG8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=Ow6Dxx0bJnw:o0R6T8WOMG8:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/Ow6Dxx0bJnw" height="1" width="1"/>]]></content:encoded>


<dc:subject>Music</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2011-12-28T22:49:40-08:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2011/12/best-music-of-2011.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2011/11/win8-dp-on-samsung-series-7-slate.html">
<title>Windows 8 Developer Preview on Samsung Series 7 Slate</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/U4qoS7O9JdI/win8-dp-on-samsung-series-7-slate.html</link>
<description>Please go to my new blog post which covers installing Windows 8 Consumer Preview on your Samsung Series 7 Slate. (Developer Preview is old news, son! What are you still doing here? :)</description>
<content:encoded><![CDATA[<p>Please go to my new blog post which covers <a href="http://bradwilson.typepad.com/blog/2012/03/win8-cp-on-ss7s.html">installing Windows 8 Consumer Preview on your Samsung Series 7 Slate</a>. (Developer Preview is old news, son! What are you still doing here? :)</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=U4qoS7O9JdI:laMDrrUJg5g:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=U4qoS7O9JdI:laMDrrUJg5g:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=U4qoS7O9JdI:laMDrrUJg5g:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=U4qoS7O9JdI:laMDrrUJg5g:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=U4qoS7O9JdI:laMDrrUJg5g:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/U4qoS7O9JdI" height="1" width="1"/>]]></content:encoded>


<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2011-11-20T16:05:16-08:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2011/11/win8-dp-on-samsung-series-7-slate.html</feedburner:origLink></item>
<item rdf:about="http://bradwilson.typepad.com/blog/2011/09/making-hyper-v-internal-network-private.html">
<title>Making Hyper-V Internal Network Private</title>
<link>http://feedproxy.google.com/~r/BradWilson/~3/q9R1dOeqORU/making-hyper-v-internal-network-private.html</link>
<description>Today, I installed Hyper-V on my Windows 8 machine so I could make a VM for a demo I'm giving later this week. I set up the virtual network as an internal network, and then used Windows 8's internal bridging...</description>
<content:encoded><![CDATA[<p>Today, I installed Hyper-V on my Windows 8 machine so I could make a VM for a demo I'm giving later this week. I set up the virtual network as an internal network, and then used Windows 8's internal bridging system to bridge the internal network over to the live WiFi.</p>
<p><b>DISCLAIMER:</b> You're about to mess with registry settings and network settings. You could seriously break things if you do it wrong, and there's no guarantee I've done everything right. Make sure you have a backup before doing anything like this.</p>

<p>For the most part, the network just works. The VM gets an IP address from Hyper-V on the private network, and it's able to get out to the public network transparently. The one problem is that the resulting network bridge is labeled as a "public" network. This means that the host could ping the VM, but the VM couldn't ping the host. Since Windows doesn't see any Internet path on the shared network, it marks it public without any option for making it private:</p>
<p><a href="http://www.flickr.com/photos/dotnetguy/6183947950/" title="Hyper-V Public Network by Brad Wilson, on Flickr"><img src="http://farm7.static.flickr.com/6172/6183947950_166a7148c5_o.png" width="650" height="457" alt="Hyper-V Public Network"></a></p>
<p>The key is to <a href="http://msdn.microsoft.com/en-us/library/ff557037.aspx">trick Windows into thinking that the network is a point-to-point network</a> instead of a traditional Ethernet network, so that it will always be considered a private network. To do this, open REGEDIT and navigate to the section of the registry that contains the network drivers:</p>
<pre>HKEY_LOCAL_MACHINE\<br />&nbsp; &nbsp; System\<br />&nbsp; &nbsp; &nbsp; &nbsp; Current Control Set\<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Control\<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Class\<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {4d36e972-e325-11ce-bfc1-08002be10318}</pre>
<p>Inside this key, you'll find a couple dozen keys for various network adapters. You're looking for the key(s) whose DriverDesc value is "Microsoft Virtual Switch Network Adapter". When you find that key, you need to add a new DWORD value named "*NdisDeviceType" with a value of "1", as illustrated below:</p>
<p><a href="http://www.flickr.com/photos/dotnetguy/6183428469/" title="Hyper-V Public Network by Brad Wilson, on Flickr"><img src="http://farm7.static.flickr.com/6173/6183428469_98e54c3e81_o.png" width="650" height="387" alt="Hyper-V Public Network"></a></p>
<p>Once you've done this, then reboot the host PC. Once you've rebooted, the network device will not show up in the Network and Sharing Center any more, since point to point network devices don't show in that list. Now the VM will have a private network with the host, so it will be able to access anything that the host normally permits to go through the private section of the firewall.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/BradWilson?a=q9R1dOeqORU:rgL3o4ivAkA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=q9R1dOeqORU:rgL3o4ivAkA:dnMXMwOfBR0"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=dnMXMwOfBR0" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=q9R1dOeqORU:rgL3o4ivAkA:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/BradWilson?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/BradWilson?a=q9R1dOeqORU:rgL3o4ivAkA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/BradWilson?i=q9R1dOeqORU:rgL3o4ivAkA:V_sGLiPBpWU" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/BradWilson/~4/q9R1dOeqORU" height="1" width="1"/>]]></content:encoded>


<dc:subject>Technical</dc:subject>

<dc:creator>Brad Wilson</dc:creator>
<dc:date>2011-09-25T19:51:01-07:00</dc:date>
<feedburner:origLink>http://bradwilson.typepad.com/blog/2011/09/making-hyper-v-internal-network-private.html</feedburner:origLink></item>


</rdf:RDF><!-- ph=1 -->

