http://www.symbolsource.org/Public/Metadata/NuGet/Project/SignalR.Client/0.3.3/Release/.NETFramework,Version%3Dv4.0/SignalR.Client/SignalR.Client/SignalR/TaskAsyncHelper.cs?ImageName=SignalR.Client
http://dotnetinside.com/en/type/SignalR.Hosting.AspNet/TaskAsyncHelper/0.5.1.10822
Linq grouping
http://weblogs.asp.net/dixin/understanding-linq-to-objects-3-query-methods
Nice Helper code
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace SignalR {
internal static class TaskAsyncHelper {
private static Task MakeEmpty() {
return FromResult<object>(null);
}
public static Task Empty {
get {
// we have to return a new one every time, other wise the task will be disposed
return MakeEmpty();
}
}
public static Task Catch(this Task task) {
return task.ContinueWith(t => {
if (t != null && t.IsFaulted) {
var ex = t.Exception;
Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
}
return t;
}).Unwrap();
}
public static Task<T> Catch<T>(this Task<T> task) {
return task.ContinueWith(t => {
if (t != null && t.IsFaulted) {
var ex = t.Exception;
Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
}
return t;
})
.Unwrap();
}
public static Task Success(this Task task, Action<Task> successor) {
return task.ContinueWith(_ => {
if (task.IsCanceled || task.IsFaulted) {
return task;
}
return Task.Factory.StartNew(() => successor(task));
}).Unwrap();
}
public static Task Success<TResult>(this Task<TResult> task, Action<Task<TResult>> successor) {
return task.ContinueWith(_ => {
if (task.IsCanceled || task.IsFaulted) {
return task;
}
return Task.Factory.StartNew(() => successor(task));
}).Unwrap();
}
public static Task<TResult> Success<TResult>(this Task task, Func<Task, TResult> successor) {
return task.ContinueWith(_ => {
if (task.IsFaulted) {
return FromError<TResult>(task.Exception);
}
if (task.IsCanceled) {
return Cancelled<TResult>();
}
return Task.Factory.StartNew(() => successor(task));
}).Unwrap();
}
public static Task<TResult> Success<T, TResult>(this Task<T> task, Func<Task<T>, TResult> successor) {
return task.ContinueWith(_ => {
if (task.IsFaulted) {
return FromError<TResult>(task.Exception);
}
if (task.IsCanceled) {
return Cancelled<TResult>();
}
return Task.Factory.StartNew(() => successor(task));
}).Unwrap();
}
public static Task AllSucceeded(this Task[] tasks, Action continuation) {
return AllSucceeded(tasks, _ => continuation());
}
public static Task AllSucceeded(this Task[] tasks, Action<Task[]> continuation) {
return Task.Factory.ContinueWhenAll(tasks, _ => {
var cancelledTask = tasks.FirstOrDefault(task => task.IsCanceled);
if (cancelledTask != null)
throw new TaskCanceledException();
var allExceptions =
tasks.Where(task => task.IsFaulted).SelectMany(task => task.Exception.InnerExceptions).ToList();
if (allExceptions.Count > 0) {
throw new AggregateException(allExceptions);
}
return Task.Factory.StartNew(() => continuation(tasks));
}).Unwrap();
}
public static Task<T> AllSucceeded<T>(this Task[] tasks, Func<T> continuation) {
return Task.Factory.ContinueWhenAll(tasks, _ => {
var cancelledTask = tasks.FirstOrDefault(task => task.IsCanceled);
if (cancelledTask != null)
throw new TaskCanceledException();
var allExceptions =
tasks.Where(task => task.IsFaulted).SelectMany(task => task.Exception.InnerExceptions).ToList();
if (allExceptions.Count > 0) {
throw new AggregateException(allExceptions);
}
return Task.Factory.StartNew(continuation);
}).Unwrap();
}
public static Task<T> FromResult<T>(T value) {
var tcs = new TaskCompletionSource<T>();
tcs.SetResult(value);
return tcs.Task;
}
private static Task<T> FromError<T>(Exception e) {
var tcs = new TaskCompletionSource<T>();
tcs.SetException(e);
return tcs.Task;
}
private static Task<T> Cancelled<T>() {
var tcs = new TaskCompletionSource<T>();
tcs.SetCanceled();
return tcs.Task;
}
}
}
Resources
http://msdn.microsoft.com/en-us/library/ff963553.aspx
http://www.microsoft.com/en-us/download/confirmation.aspx?id=19222
Article
http://www.albahari.com/nutshell/cs4ch22.aspx
http://dotnetcodr.com/2014/03/18/continuation-tasks-in-net-tpl-many-tasks-continued-by-a-single-task/
Stackoverflow
http://stackoverflow.com/questions/15938254/task-results-into-a-single-list