Task.Finally extension, good, bad, or ugly? I wrote this, and it has helped to avoid the 'Some exception weren't handled' problem. Is there something glaringly wrong with this that I might have missed?

    /// &lt;summary&gt;
    /// Handles any exceptions on this task, and executes action on specified scheduler.
    /// &lt;/summary&gt;
    /// &lt;param name="task"&gt;The task.&lt;/param&gt;
    /// &lt;param name="exceptionHandler"&gt;The exception handler.&lt;/param&gt;
    /// &lt;param name="finalAction"&gt;The final action.&lt;/param&gt;
    /// &lt;param name="scheduler"&gt;The scheduler.&lt;/param&gt;
    public static void Finally(this Task task, Action&lt;Exception&gt; exceptionHandler, 
                                               Action finalAction, TaskScheduler scheduler)
    {
        task.ContinueWith(t =&gt;
        {
            if(finalAction != null) finalAction();

            if(t.IsCanceled || !t.IsFaulted || exceptionHandler == null) return;
            var innerException = t.Exception.Flatten().InnerExceptions.FirstOrDefault();
            exceptionHandler(innerException ?? t.Exception);
        }, scheduler);
    }
I think what you've really got here is two extension methods hiding inside one.  Your method is doing the work of both a "finally" and a "catch", and I recommend refactoring it into two methods.  The catch method may look something like this:

Edit: clearly I missed checking the exception type before executing the action, but I'm away from a computer and trying to edit code with my iPhone isn't working too well. 

public static void Catch&lt;TException&gt;(this Task task, Action&lt;TException&gt; exceptionHandler, 
                                     TaskScheduler scheduler = null) where TException : Exception
{
    if (exceptionHandler == null)
        throw new ArgumentNullException("exceptionHandler cannot be null");

    task.ContinueWith(t =&gt;
    {
        if(t.IsCanceled || !t.IsFaulted || t.Exception == null) return;
        var innerException = t.Exception.Flatten().InnerExceptions.FirstOrDefault();
        exceptionHandler(innerException ?? t.Exception);
    }, scheduler ?? TaskScheduler.Default);
}


Edit: Finally got time to get back to this.  Here's an example of a complete solution:

using System;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Task.Run(() =&gt; {
                Console.WriteLine("In the Task");
                throw new ArgumentException("Thrown from task");
                //throw new Exception("Thrown from task");
            })
            .Catch&lt;Exception&gt;((e) =&gt; Console.WriteLine("Caught Exception {0}", e))
            .Catch&lt;ArgumentException&gt;((ae) =&gt; Console.WriteLine("Caught Argument Excetion {0}", ae))
            .Finally(() =&gt; Console.WriteLine("in the Finally"));

        Console.ReadKey();
        Console.ReadKey();
    }
}

static class TaskExtensions
{

    public static void Finally(this Task task, Action finalAction, 
                               TaskScheduler scheduler = null)
    {
        if (finalAction == null)
            throw new ArgumentNullException("finalAction cannot be null");

        task.ContinueWith(t =&gt; finalAction(), scheduler ?? TaskScheduler.Default);
    }

    public static Task Catch&lt;TException&gt;(this Task task, Action&lt;TException&gt; exceptionHandler,
                                         TaskScheduler scheduler = null) where TException : Exception
    {
        if (exceptionHandler == null)
            throw new ArgumentNullException("exceptionHandler cannot be null");

        task.ContinueWith(t =&gt;
        {
            if (t.IsCanceled || !t.IsFaulted || t.Exception == null) 
                return;

            var exception =
                t.Exception.Flatten().InnerExceptions.FirstOrDefault() ?? t.Exception;

            if (exception is TException)
            {
                exceptionHandler((TException) exception);
            }
        }, scheduler ?? TaskScheduler.Default);

        return task;
    }
}
}