Task with feedback dialog helper class I'm currently working in a Windows.Forms project where its very common that I need to show a responsive feedback form while a task runs. These tasks take typically around 5 to 10 seconds to complete and the user can't do anything else until the task has successfully finished or failed.

To keep the UI responsive I've cooked up a little helper class. I'm pretty new to tasks and the async programming environment so I am not sure if I'm overkilling things here or going off in a completely wrong direction:

This is the small helper class:

internal sealed class TaskManagerWithFeedbackDialog&lt;TController&gt; where TController : IViewController, new() 
{
    public static Task&lt;TReturn&gt; RunTask&lt;TReturn&gt;(Func&lt;TReturn&gt; func)
    {
        if (func == null)
        {
            throw new ArgumentNullException("func");
        }

        var manager = new _AsyncTaskManager&lt;TReturn&gt;(func);

        using (var view = new TController())
        {
            var task = manager.Start(view);
            view.ShowViewDialog();
            return task;
        }
    }

    private class _AsyncTaskManager&lt;T&gt;
    {
        private readonly Func&lt;T&gt; taskFunc;

        public _AsyncTaskManager(Func&lt;T&gt; func)
        {
            taskFunc = func;
        }

        public Task&lt;T&gt; Start(IViewController feedBackView)
        {
            var task = Task.Factory.StartNew(taskFunc);

            task.ContinueWith(t =&gt;
            {
                feedBackView.CloseView();
            }, TaskContinuationOptions.OnlyOnFaulted);

            task.ContinueWith(t =&gt;
            {
                feedBackView.CloseView();
                return t.Result;
            }, TaskContinuationOptions.NotOnFaulted);

            return task;
        }
    }
}


Where the implementation of IViewController.CloseView() would look like this:

public virtual void CloseView()
{
    if (View.InvokeRequired)
    {
        View.Invoke(new Action(View.Close));
    }
    else
    {
        View.Close();
    }
}


Another issue I am not sure about is where is the best place to handle ArregateException?. Right now I don't handle anything as I don't need to clean up anything if a task fails. I simply check the returned task for any errors. Is this the right thing to do? Do async tasks always fail 'silently'? If I needed to clean up, where would it be? Inside .ContinueWith( .... , TaskContinuationOptions.OnlyOnFaulted)?
Few minor things:


If TaskManagerWithFeedbackDialog is not a nested class then internal is redundant and can be dropped.
TaskManagerWithFeedbackDialog has - so far - just one single static method. Until you will add more methods make it a static class. No need to create any instance.
TController instance is disposed just after task started (see it's wrapped in using). When you will invoke CloseView() you will call it on an already disposed object. Is it just a factory? Call it *Factory instead of *Controller. Is it a controller? Don't dispose it immediately but when you close the view (and check why your Dispose() method does nothing).
Why RunTask() instead of StartNew() or - better - Run() as Task and TaskFactory methods? I'd favor consistency with framework classes.
Is there a specific reason you're using Task.Factory.StartNew() instead of Task.Run()? EDIT: OK, you're with .NET 4.0.
_AsyncTaskManager (which BTW shouldn't be prefixed, it's optional for private fields and to avoid for types) is superfluous. It's just one method, it has no state and it's not persisted or passed around. You don't need a class but a simple private method.
Task has a fluid interface, you can concatenate method calls return Task.Run(...).ContinueWith(...).ContinueWith(...). 
In CloseView() you wait for dispatched action to terminate but you don't actually need to wait for UI to push thread back to the pool, in WinForms you may simply use BeginInvoke() because it doesn't need EndInvoke() to be called.


Ideally you wouldn't even need continuation tasks:

Task.Factory.StartNew(() =&gt; {
    try
    {
        return taskFunc();
    }
    finally
    {
        feedBackView.CloseView();
    }
});


About exception management: you're doing right, if it's the way you want to handle errors. You close your view but AggregateException goes unnoticed. Here you may want to log such errors or to propagate them to UI thread (for example) again using BeginInvoke. See MSDN for more details.