Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / corlib / System.Threading.Tasks / TaskFactory.cs
index d69c9cd1e8778a3160b3def4e3aa3b72b6d2ebc8..a558c622c5ebf2cf5a3158394a86ecd9da609966 100644 (file)
@@ -1,11 +1,12 @@
-#if NET_4_0 || BOOTSTRAP_NET_4_0
 // 
 // TaskFactory.cs
 //  
-// Author:
+// Authors:
 //       Jérémie "Garuma" Laval <jeremie.laval@gmail.com>
+//       Marek Safar <marek.safar@gmail.com>
 // 
 // Copyright (c) 2009 Jérémie "Garuma" Laval
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
 // 
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-using System;
-using System.Threading;
+#if NET_4_0
 
 namespace System.Threading.Tasks
 {
-       
        public class TaskFactory
        {
-               TaskScheduler scheduler;
-               TaskCreationOptions options;
-               TaskContinuationOptions contOptions;
-               CancellationToken token;
+               readonly TaskScheduler scheduler;
+               TaskCreationOptions creationOptions;
+               TaskContinuationOptions continuationOptions;
+               CancellationToken cancellationToken;
                
-               #region ctors
                public TaskFactory ()
-                       : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Current)
+                       : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, null)
                {
                }
 
-               public TaskFactory (CancellationToken token)
-                       : this (token, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Current)
+               public TaskFactory (CancellationToken cancellationToken)
+                       : this (cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
                {       
                }
 
@@ -54,62 +52,110 @@ namespace System.Threading.Tasks
                {       
                }
                
-               public TaskFactory (TaskCreationOptions options, TaskContinuationOptions contOptions)
-                       : this (CancellationToken.None, options, contOptions, TaskScheduler.Current)
+               public TaskFactory (TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
+                       : this (CancellationToken.None, creationOptions, continuationOptions, null)
                {       
                }
                
-               public TaskFactory (CancellationToken token, TaskCreationOptions options, TaskContinuationOptions contOptions,
+               public TaskFactory (CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions,
                                    TaskScheduler scheduler)
                {
-                       this.token = token;
+                       this.cancellationToken = cancellationToken;
                        this.scheduler = scheduler;
-                       this.options = options;
-                       this.contOptions = contOptions;
+                       this.creationOptions = creationOptions;
+                       this.continuationOptions = continuationOptions;
+
+                       CheckContinuationOptions (continuationOptions);
+               }
+               
+               public TaskScheduler Scheduler {
+                       get {
+                               return scheduler;
+                       }
+               }
+               
+               public TaskContinuationOptions ContinuationOptions {
+                       get {
+                               return continuationOptions;
+                       }
+               }
+               
+               public TaskCreationOptions CreationOptions {
+                       get {
+                               return creationOptions;
+                       }
+               }
+               
+               public CancellationToken CancellationToken {
+                       get {
+                               return cancellationToken;
+                       }
+               }
+
+               internal static void CheckContinuationOptions (TaskContinuationOptions continuationOptions)
+               {
+                       if ((continuationOptions & (TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.NotOnRanToCompletion)) != 0)
+                               throw new ArgumentOutOfRangeException ("continuationOptions");
+
+                       const TaskContinuationOptions long_running = TaskContinuationOptions.LongRunning | TaskContinuationOptions.ExecuteSynchronously;
+                       if ((continuationOptions & long_running) == long_running)
+                               throw new ArgumentOutOfRangeException ("continuationOptions", "Synchronous continuations cannot be long running");
                }
-               #endregion
                
                #region StartNew for Task
                public Task StartNew (Action action)
                {
-                       return StartNew (action, token, options, scheduler);
+                       return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task StartNew (Action action, CancellationToken token)
+               public Task StartNew (Action action, CancellationToken cancellationToken)
                {
-                       return StartNew (action, token, options, scheduler);
+                       return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task StartNew (Action action, TaskCreationOptions options)
+               public Task StartNew (Action action, TaskCreationOptions creationOptions)
                {
-                       return StartNew (action, token, options, scheduler);
+                       return StartNew (action, cancellationToken, creationOptions, GetScheduler ());
                }
-               
-               public Task StartNew (Action<object> action, object state)
+
+               public Task StartNew (Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
                {
-                       return StartNew (action, state, token, options, scheduler);
+                       Task t = new Task (action, cancellationToken, creationOptions);
+
+                       //
+                       // Don't start cancelled task it would throw an exception
+                       //
+                       if (!t.IsCompleted)
+                               t.Start (scheduler);
+
+                       return t;
                }
                
-               public Task StartNew (Action<object> action, object state, CancellationToken token)
+               public Task StartNew (Action<object> action, object state)
                {
-                       return StartNew (action, state, token, options, scheduler);
+                       return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task StartNew (Action<object> action, object state, TaskCreationOptions options)
+               public Task StartNew (Action<object> action, object state, CancellationToken cancellationToken)
                {
-                       return StartNew (action, state, token, options, scheduler);
+                       return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task StartNew (Action action, CancellationToken token, TaskCreationOptions options, TaskScheduler scheduler)
+               public Task StartNew (Action<object> action, object state, TaskCreationOptions creationOptions)
                {
-                       return StartNew ((o) => action (), null, token, options, scheduler);
+                       return StartNew (action, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task StartNew (Action<object> action, object state, CancellationToken token, TaskCreationOptions options,
+               public Task StartNew (Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions,
                                      TaskScheduler scheduler)
                {
-                       Task t = new Task (action, state, options);
-                       t.Start (scheduler);
+                       Task t = new Task (action, state, cancellationToken, creationOptions);
+
+                       //
+                       // Don't start cancelled task it would throw an exception
+                       //
+                       if (!t.IsCompleted)
+                               t.Start (scheduler);
                        
                        return t;
                }
@@ -118,51 +164,64 @@ namespace System.Threading.Tasks
                #region StartNew for Task<TResult>      
                public Task<TResult> StartNew<TResult> (Func<TResult> function)
                {
-                       return StartNew<TResult> (function, token, options, scheduler);
+                       return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task<TResult> StartNew<TResult> (Func<TResult> function, TaskCreationOptions options)
+               public Task<TResult> StartNew<TResult> (Func<TResult> function, TaskCreationOptions creationOptions)
                {
-                       return StartNew<TResult> (function, token, options, scheduler);
+                       return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
 
                }
                
-               public Task<TResult> StartNew<TResult> (Func<TResult> function, CancellationToken token)
+               public Task<TResult> StartNew<TResult> (Func<TResult> function, CancellationToken cancellationToken)
                {
-                       return StartNew<TResult> (function, token, options, scheduler);
+                       return StartNew<TResult> (function, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew<TResult> (Func<TResult> function,
-                                                       CancellationToken token,
-                                                       TaskCreationOptions options,
+                                                       CancellationToken cancellationToken,
+                                                       TaskCreationOptions creationOptions,
                                                        TaskScheduler scheduler)
                {
-                       return StartNew<TResult> ((o) => function (), null, token, options, scheduler);
+                       var t = new Task<TResult> (function, cancellationToken, creationOptions);
+
+                       //
+                       // Don't start cancelled task it would throw an exception
+                       //
+                       if (!t.IsCompleted)
+                               t.Start (scheduler);
+
+                       return t;
                }
                
                public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state)
                {
-                       return StartNew<TResult> (function, state, token, options, scheduler);
+                       return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, CancellationToken token)
+               public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, CancellationToken cancellationToken)
                {
-                       return StartNew<TResult> (function, state, token, options, scheduler);
+                       return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
-               public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, TaskCreationOptions options)
+               public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state, TaskCreationOptions creationOptions)
                {
-                       return StartNew<TResult> (function, state, token, options, scheduler);
+                       return StartNew<TResult> (function, state, cancellationToken, creationOptions, GetScheduler ());
                }
                
                public Task<TResult> StartNew<TResult> (Func<object, TResult> function, object state,
-                                                       CancellationToken token,
-                                                       TaskCreationOptions options,
+                                                       CancellationToken cancellationToken,
+                                                       TaskCreationOptions creationOptions,
                                                        TaskScheduler scheduler)
                {
-                       Task<TResult> t = new Task<TResult> (function, state, token, options);
-                       t.Start (scheduler);
+                       var t = new Task<TResult> (function, state, cancellationToken, creationOptions);
                        
+                       //
+                       // Don't start cancelled task it would throw an exception
+                       //
+                       if (!t.IsCompleted)
+                               t.Start (scheduler);
+
                        return t;
                }
                #endregion
@@ -171,776 +230,432 @@ namespace System.Threading.Tasks
                
                public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken token)
+               public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
-               public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken token, 
-                                            TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
+               public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
                {
-                       AtomicBoolean trigger = new AtomicBoolean ();
-                       Task commonContinuation = new Task (null);
-                       
-                       foreach (Task t in tasks) {
-                               Task cont = new Task ((o) => { continuationAction ((Task)o); }, t, token, options);
-                               t.ContinueWithCore (cont, continuationOptions, scheduler, trigger.TrySet);
-                               cont.ContinueWithCore (commonContinuation, TaskContinuationOptions.None, scheduler);
-                       }
-                       
-                       return commonContinuation;
+                       CheckContinueArguments (tasks, continuationAction, continuationOptions, scheduler);
+
+                       var cont = Task.WhenAnyCore (tasks).ContinueWith (TaskActionInvoker.CreateSelected (continuationAction), cancellationToken, continuationOptions, scheduler);
+
+                       return cont;
                }
                
-               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction)
+               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
+                                                               Action<Task<TAntecedentResult>> continuationAction)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
-                                                               CancellationToken token)
+               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
+                                                               Action<Task<TAntecedentResult>> continuationAction,
+                                                               CancellationToken cancellationToken)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
+               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
+                                                               Action<Task<TAntecedentResult>> continuationAction,
                                                                TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
-               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,
-                                                               CancellationToken token, TaskContinuationOptions continuationOptions,
+               public Task ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
+                                                               Action<Task<TAntecedentResult>> continuationAction,
+                                                               CancellationToken cancellationToken,
+                                                               TaskContinuationOptions continuationOptions,
                                                                TaskScheduler scheduler)
                {
-                       return ContinueWhenAny ((Task[]) tasks, (o) => continuationAction ((Task<TAntecedentResult>)o),
-                                               token, continuationOptions, scheduler);
+                       return ContinueWhenAny ((Task[]) tasks,
+                                               (o) => continuationAction ((Task<TAntecedentResult>)o),
+                                               cancellationToken, continuationOptions, scheduler);
                }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationAction)
+
+               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationFunction)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationAction,
-                                                              CancellationToken token)
+
+               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
+                                                              Func<Task, TResult> continuationFunction,
+                                                              CancellationToken cancellationToken)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationAction,
+
+               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
+                                                              Func<Task, TResult> continuationFunction,
                                                               TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks, Func<Task, TResult> continuationAction,
-                                                              CancellationToken token,
+               public Task<TResult> ContinueWhenAny<TResult> (Task[] tasks,
+                                                              Func<Task, TResult> continuationFunction,
+                                                              CancellationToken cancellationToken,
                                                               TaskContinuationOptions continuationOptions,
                                                               TaskScheduler scheduler)
                {
-                       throw new NotImplementedException ();
+                       CheckContinueArguments (tasks, continuationFunction, continuationOptions, scheduler);
+
+                       var cont = Task.WhenAnyCore (tasks).ContinueWith<TResult> (TaskActionInvoker.CreateSelected (continuationFunction), cancellationToken, continuationOptions, scheduler);
+
+                       return cont;
                }
-               
-               [MonoTODO]
+
                public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
-                                                                                 Func<Task<TAntecedentResult>, TResult> continuationAction)
+                                                                                 Func<Task<TAntecedentResult>, TResult> continuationFunction)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
-               [MonoTODO]
                public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
-                                                                                 Func<Task<TAntecedentResult>, TResult> continuationAction,
-                                                                                 CancellationToken token)
+                                                                                 Func<Task<TAntecedentResult>, TResult> continuationFunction,
+                                                                                 CancellationToken cancellationToken)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
-               
-               [MonoTODO]
+
                public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
-                                                                                 Func<Task<TAntecedentResult>, TResult> continuationAction,
+                                                                                 Func<Task<TAntecedentResult>, TResult> continuationFunction,
                                                                                  TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, continuationOptions, scheduler);
+                       return ContinueWhenAny (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
 
-               [MonoTODO]
                public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
-                                                                                 Func<Task<TAntecedentResult>, TResult> continuationAction,
-                                                                                 CancellationToken token,
+                                                                                 Func<Task<TAntecedentResult>, TResult> continuationFunction,
+                                                                                 CancellationToken cancellationToken,
                                                                                  TaskContinuationOptions continuationOptions,
                                                                                  TaskScheduler scheduler)
                {
-                       return ContinueWhenAny<TResult> ((Task[])tasks, (t) => continuationAction((Task<TAntecedentResult>)t), token, continuationOptions, scheduler);
+                       return ContinueWhenAny<TResult> ((Task[])tasks,
+                                                        (t) => continuationFunction((Task<TAntecedentResult>)t),
+                                                        cancellationToken,
+                                                        continuationOptions,
+                                                        scheduler);
                }
                
-               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationFunction)
+               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationFunction, CancellationToken token)
+               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationFunction,
+               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction,
                                             TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationFunction, CancellationToken token,
+               public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
                                             TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
                {
-                       CountdownEvent evt = new CountdownEvent (tasks.Length);
-                       Task cont = new Task ((o) => continuationFunction ((Task[])o), tasks, token, options);
-                       
-                       foreach (Task t in tasks)
-                               t.ContinueWithCore (cont, continuationOptions, scheduler, evt.Signal);
-                       
+                       CheckContinueArguments (tasks, continuationAction, continuationOptions, scheduler);
+
+                       var cont = Task.WhenAllCore (tasks).ContinueWith (TaskActionInvoker.Create (continuationAction, tasks), cancellationToken, continuationOptions, scheduler);
+
                        return cont;
                }
                
                public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                               Action<Task<TAntecedentResult>[]> continuationFunction)
+                                                               Action<Task<TAntecedentResult>[]> continuationAction)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                               Action<Task<TAntecedentResult>[]> continuationFunction, CancellationToken token)
+                                                               Action<Task<TAntecedentResult>[]> continuationAction, CancellationToken cancellationToken)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
-               public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationFunction,
+               public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,
                                                                TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, continuationOptions, scheduler);
+                       return ContinueWhenAll (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks, 
-                                                               Action<Task<TAntecedentResult>[]> continuationFunction,
-                                                               CancellationToken token, TaskContinuationOptions continuationOptions,
+                                                               Action<Task<TAntecedentResult>[]> continuationAction,
+                                                               CancellationToken cancellationToken, TaskContinuationOptions continuationOptions,
                                                                TaskScheduler scheduler)
                {
-                       return ContinueWhenAll ((Task[]) tasks, (o) => continuationFunction (tasks), token,
+                       return ContinueWhenAll ((Task[]) tasks, (o) => continuationAction (tasks), cancellationToken,
                                                continuationOptions, scheduler);
                }
                
                public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction)
                {
-                       return ContinueWhenAll<TResult> (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll<TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction,
                                                               TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAll<TResult> (tasks, continuationFunction, token, continuationOptions, scheduler);
+                       return ContinueWhenAll<TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction,
-                                                              CancellationToken token)
+                                                              CancellationToken cancellationToken)
                {
-                       return ContinueWhenAll<TResult> (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll<TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TResult> (Task[] tasks, Func<Task[], TResult> continuationFunction,
-                                                              CancellationToken token,
+                                                              CancellationToken cancellationToken,
                                                               TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
                {
-                       CountdownEvent evt = new CountdownEvent (tasks.Length);
-                       Task<TResult> cont = new Task<TResult> ((o) => continuationFunction ((Task[])o), tasks, token, options);
-                       
-                       foreach (Task t in tasks)
-                               t.ContinueWithCore (cont, continuationOptions, scheduler, evt.Signal);
-                       
+                       CheckContinueArguments (tasks, continuationFunction, continuationOptions, scheduler);
+
+                       var cont = Task.WhenAllCore (tasks).ContinueWith<TResult> (TaskActionInvoker.Create (continuationFunction, tasks), cancellationToken, continuationOptions, scheduler);
+
                        return cont;
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
                                                                                  Func<Task<TAntecedentResult>[], TResult> continuationFunction)
                {
-                       return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks, 
                                                                                  Func<Task<TAntecedentResult>[], TResult> continuationFunction,
                                                                                  TaskContinuationOptions continuationOptions)
                {
-                       return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, token, continuationOptions, scheduler);
+                       return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
                                                                                  Func<Task<TAntecedentResult>[], TResult> continuationFunction,
-                                                                                 CancellationToken token)
+                                                                                 CancellationToken cancellationToken)
                {
-                       return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, token, contOptions, scheduler);
+                       return ContinueWhenAll<TAntecedentResult, TResult> (tasks, continuationFunction, cancellationToken, continuationOptions, GetScheduler ());
                }
                
                public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks, 
                                                                                  Func<Task<TAntecedentResult>[], TResult> continuationFunction,
-                                                                                 CancellationToken token,
+                                                                                 CancellationToken cancellationToken,
                                                                                  TaskContinuationOptions continuationOptions,
                                                                                  TaskScheduler scheduler)
                {
                        return ContinueWhenAll<TResult> ((Task[]) tasks,
                                                         (o) => continuationFunction (tasks),
-                                                        token,
+                                                        cancellationToken,
                                                         continuationOptions, scheduler);
                }
 
                #endregion
+
+               #region FromAsync IAsyncResult
                
-               #region FromAsync
-               // For these methods to work we first have to convert the ThreadPool to use Tasks as it
-               // is doing in 4.0, then all that is remaining is to identify the Task on which is 
-               // run the async operation (probably with some additional state in a IAsyncResult subclass)
-               // and call its ContinueWith method accordingly
-               
-               const string errorMsg = "Mono's thread pool doesn't support this operation yet";
-               
-               [MonoLimitation(errorMsg)]
                public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod)
                {
-                       return FromAsync (asyncResult, endMethod, options);
+                       return FromAsync (asyncResult, endMethod, creationOptions);
                }
                
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod,
-                                      TaskCreationOptions creationOptions)
+               public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod, TaskCreationOptions creationOptions)
                {
-                       return FromAsync (asyncResult, endMethod, creationOptions);
+                       return FromAsync (asyncResult, endMethod, creationOptions, GetScheduler ());
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod,
-                                      TaskCreationOptions creationOptions, TaskScheduler scheduler)
+
+               public Task FromAsync (IAsyncResult asyncResult, Action<IAsyncResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
                {
-                       throw new NotSupportedException (errorMsg);
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       return TaskFactory<object>.FromIAsyncResult (asyncResult,
+                               l => {
+                                       endMethod (asyncResult);
+                                       return null;
+                               }, creationOptions, scheduler);
                }
                
-               [MonoLimitation(errorMsg)]
                public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
                {
-                       return FromAsync<TResult> (asyncResult, endMethod, options);
+                       return FromAsync<TResult> (asyncResult, endMethod, creationOptions);
                }
                
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod,
-                                                        TaskCreationOptions creationOptions)
+               public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions)
                {
-                       return FromAsync<TResult> (asyncResult, endMethod, creationOptions);
+                       return FromAsync<TResult> (asyncResult, endMethod, creationOptions, GetScheduler ());
                }
                
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod,
-                                                        TaskCreationOptions creationOptions, TaskScheduler scheduler)
+               public Task<TResult> FromAsync<TResult> (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return TaskFactory<TResult>.FromIAsyncResult (asyncResult, endMethod, creationOptions, scheduler);
                }
-               
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync (Func<AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
-                                      object state)
+
+               #endregion
+
+               #region FromAsync Begin/End Method
+
+               public Task FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod, object state)
                {
-                       return FromAsync<object> ((a, c, o) => beginMethod (c, o), endMethod, state, options);
+                       return FromAsync (beginMethod, endMethod, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync (Func<AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
-                                      object state, TaskCreationOptions creationOptions)
+
+               public Task FromAsync (Func<AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+                                                          object state, TaskCreationOptions creationOptions)
                {
-                       return FromAsync<object> ((a, c, o) => beginMethod (c, o), endMethod, state, creationOptions);
+                       return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
+                               l => { endMethod (l); return null; },
+                               state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
-                                             TArg1 arg1, object state)
+
+               public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+                                                 TArg1 arg1, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+
+               public Task FromAsync<TArg1> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
                                              TArg1 arg1, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
+                               l => { endMethod (l); return null; },
+                               arg1, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+
+               public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
+                                                    Action<IAsyncResult> endMethod,
                                                     TArg1 arg1, TArg2 arg2, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+
+               public Task FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
+                                                    Action<IAsyncResult> endMethod,
                                                     TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
+                               l => { endMethod (l); return null; },
+                               arg1, arg2, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+
+               public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
                                                            TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
+
+               public Task FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Action<IAsyncResult> endMethod,
                                                            TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
-               }               
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                        Func<IAsyncResult, TResult> endMethod,
+                       if (endMethod == null)
+                               throw new ArgumentNullException ("endMethod");
+
+                       return TaskFactory<object>.FromAsyncBeginEnd (beginMethod,
+                               l => { endMethod (l); return null; },
+                               arg1, arg2, arg3, state, creationOptions);
+               }
+
+               public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                         object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                        Func<IAsyncResult, TResult> endMethod,
-                                      object state, TaskCreationOptions creationOptions)
+
+               public Task<TResult> FromAsync<TResult> (Func<AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
+                                                        object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                               Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                                TArg1 arg1, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                            Func<IAsyncResult, TResult> endMethod,
-                                                            TArg1 arg1, object state, TaskCreationOptions creationOptions)
+
+               public Task<TResult> FromAsync<TArg1, TResult> (Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
+                                                               TArg1 arg1, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod,
+
+               public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
                                                                       Func<IAsyncResult, TResult> endMethod,
                                                                       TArg1 arg1, TArg2 arg2, object state)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return FromAsync (beginMethod, endMethod, arg1, arg2, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                      Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync<TArg1, TArg2, TResult> (Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                                       TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
                {
-                       throw new NotSupportedException (errorMsg);
+                       return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, state, creationOptions);
                }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                             Func<IAsyncResult, TResult> endMethod,
+
+               public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
                                                                              TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
                {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                             Func<IAsyncResult, TResult> endMethod,
-                                                                             TArg1 arg1, TArg2 arg2, TArg3 arg3, object state,
-                                                                             TaskCreationOptions creationOptions)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               #endregion
-               
-               public TaskScheduler Scheduler {
-                       get {
-                               return scheduler;
-                       }
-               }
-               
-               public TaskContinuationOptions ContinuationOptions {
-                       get {
-                               return contOptions;
-                       }
-               }
-               
-               public TaskCreationOptions CreationOptions {
-                       get {
-                               return options;
-                       }
-               }
-               
-               public CancellationToken CancellationToken {
-                       get {
-                               return token;
-                       }
+                       return FromAsync (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
                }
-       }
-       
-       public class TaskFactory<TResult>
-       {
-               TaskScheduler scheduler;
-               TaskCreationOptions options;
-               TaskContinuationOptions contOptions;
-               CancellationToken token;
-               
-               TaskFactory parent;
-               
-               #region ctors
-               public TaskFactory ()
-                       : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Current)
-               {       
-               }
-               
-               public TaskFactory (TaskScheduler scheduler)
-                       : this (CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, scheduler)
-               {       
-               }
-               
-               public TaskFactory (CancellationToken token)
-                       : this (token, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Current)
-               {       
-               }
-               
-               public TaskFactory (TaskCreationOptions options, TaskContinuationOptions contOptions)
-                       : this (CancellationToken.None, options, contOptions, TaskScheduler.Current)
-               {       
-               }
-               
-               public TaskFactory (CancellationToken token, TaskCreationOptions options, TaskContinuationOptions contOptions,
-                                   TaskScheduler scheduler)
-               {
-                       this.token = token;
-                       this.scheduler = scheduler;
-                       this.options = options;
-                       this.contOptions = contOptions;
-                       
-                       this.parent = new TaskFactory (token, options, contOptions, scheduler);
-               }
-               
-               #endregion
-               
-               #region StartNew for Task<TResult>      
-               public Task<TResult> StartNew (Func<TResult> function)
-               {
-                       return StartNew (function, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<TResult> function, TaskCreationOptions options)
-               {
-                       return StartNew (function, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<TResult> function, CancellationToken token)
-               {
-                       return StartNew (function, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<TResult> function, 
-                                              CancellationToken token,
-                                              TaskCreationOptions options,
-                                              TaskScheduler scheduler)
-               {
-                       return StartNew ((o) => function (), null, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<object, TResult> function, object state)
-               {
-                       return StartNew (function, state, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<object, TResult> function, object state, TaskCreationOptions options)
-               {
-                       return StartNew (function, state, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<object, TResult> function, object state, CancellationToken token)
-               {
-                       return StartNew (function, state, token, options, scheduler);
-               }
-               
-               public Task<TResult> StartNew (Func<object, TResult> function, object state, 
-                                              CancellationToken token,
-                                              TaskCreationOptions options,
-                                              TaskScheduler scheduler)
+
+               public Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult> (Func<TArg1, TArg2, TArg3, AsyncCallback, object, IAsyncResult> beginMethod, Func<IAsyncResult, TResult> endMethod,
+                                                                             TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, TaskCreationOptions creationOptions)
                {
-                       return parent.StartNew<TResult> (function, state, token, options, scheduler);
+                       return TaskFactory<TResult>.FromAsyncBeginEnd (beginMethod, endMethod, arg1, arg2, arg3, state, creationOptions);
                }
+
                #endregion
-               
-               #region Continue
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny (Task[] tasks,
-                                                     Func<Task, TResult> continuationAction)
-               {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
-               }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny (Task[] tasks,
-                                                     Func<Task, TResult> continuationAction,
-                                                     CancellationToken token)
-               {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
-               }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny (Task[] tasks,
-                                                     Func<Task, TResult> continuationAction,
-                                                     TaskContinuationOptions continuationOptions)
-               {
-                       return ContinueWhenAny (tasks, continuationAction, token, continuationOptions, scheduler);
-               }
 
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny (Task[] tasks,
-                                                     Func<Task, TResult> continuationAction,
-                                                     CancellationToken token,
-                                                     TaskContinuationOptions continuationOptions,
-                                                     TaskScheduler scheduler)
-               {
-                       throw new NotImplementedException ();
-               }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>, TResult> continuationAction)
-               {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
-               }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>, TResult> continuationAction,
-                                                                        CancellationToken token)
+               TaskScheduler GetScheduler ()
                {
-                       return ContinueWhenAny (tasks, continuationAction, token, contOptions, scheduler);
-               }
-               
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>, TResult> continuationAction,
-                                                                        TaskContinuationOptions continuationOptions)
-               {
-                       return ContinueWhenAny (tasks, continuationAction, token, continuationOptions, scheduler);
+                       return scheduler ?? TaskScheduler.Current;
                }
 
-               [MonoTODO]
-               public Task<TResult> ContinueWhenAny<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>, TResult> continuationAction,
-                                                                        CancellationToken token,
-                                                                        TaskContinuationOptions continuationOptions,
-                                                                        TaskScheduler scheduler)
-               {
-                       throw new NotImplementedException ();
-               }
-               
-               public Task<TResult> ContinueWhenAll (Task[] tasks,
-                                                     Func<Task[], TResult> continuationFunction)
+               static void CheckContinueArguments (Task[] tasks, object continuationAction, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
                {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
-               }
-               
-               public Task<TResult> ContinueWhenAll (Task[] tasks,
-                                                     Func<Task[], TResult> continuationFunction,
-                                                     TaskContinuationOptions continuationOptions)
-               {
-                       return ContinueWhenAll (tasks, continuationFunction, token, continuationOptions, scheduler);
-               }
-               
-               public Task<TResult> ContinueWhenAll (Task[] tasks,
-                                                     Func<Task[], TResult> continuationFunction,
-                                                     CancellationToken token)
-               {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
-               }
-               
-               public Task<TResult> ContinueWhenAll (Task[] tasks,
-                                                     Func<Task[], TResult> continuationFunction,
-                                                     CancellationToken token,
-                                                     TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
-               {
-                       CountdownEvent evt = new CountdownEvent (tasks.Length);
-                       Task<TResult> cont = new Task<TResult> ((o) => continuationFunction (tasks), tasks, token, options);
-                       
-                       foreach (Task t in tasks)
-                               t.ContinueWithCore (cont, continuationOptions, scheduler, evt.Signal);
-                       
-                       return cont;
-               }
-               
-               public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>[], TResult> continuationFunction)
-               {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
-               }
-               
-               public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>[], TResult> continuationFunction,
-                                                                        TaskContinuationOptions continuationOptions)
-               {
-                       return ContinueWhenAll (tasks, continuationFunction, token, continuationOptions, scheduler);
-               }
-               
-               public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>[], TResult> continuationFunction,
-                                                                        CancellationToken token)
-               {
-                       return ContinueWhenAll (tasks, continuationFunction, token, contOptions, scheduler);
-               }
-               
-               public Task<TResult> ContinueWhenAll<TAntecedentResult> (Task<TAntecedentResult>[] tasks,
-                                                                        Func<Task<TAntecedentResult>[], TResult> continuationFunction,
-                                                                        CancellationToken token,
-                                                                        TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
-               {
-                       CountdownEvent evt = new CountdownEvent (tasks.Length);
-                       Task<TResult> cont = new Task<TResult> ((o) => continuationFunction (tasks), tasks, token, options);
-                       
-                       foreach (Task t in tasks)
-                               t.ContinueWithCore (cont, continuationOptions, scheduler, evt.Signal);
-                       
-                       return cont;
-               }
+                       if (tasks == null)
+                               throw new ArgumentNullException ("tasks");
 
-               #endregion
-               
-               #region FromAsync
-               const string errorMsg = "Mono's thread pool doesn't support this operation yet";
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
-               {
-                       return FromAsync (asyncResult, endMethod, options);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod,
-                                               TaskCreationOptions creationOptions)
-               {
-                       return FromAsync (asyncResult, endMethod, creationOptions);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod,
-                                               TaskCreationOptions creationOptions, TaskScheduler scheduler)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (Func<AsyncCallback, Object, IAsyncResult> beginMethod,
-                                               Func<IAsyncResult, TResult> endMethod,
-                                               object state)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync (Func<AsyncCallback, Object, IAsyncResult> beginMethod,
-                                               Func<IAsyncResult, TResult> endMethod,
-                                               object state, TaskCreationOptions creationOptions)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                      Func<IAsyncResult, TResult> endMethod,
-                                                      TArg1 arg1, object state)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1> (Func<TArg1, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                      Func<IAsyncResult, TResult> endMethod,
-                                                      TArg1 arg1, object state, TaskCreationOptions creationOptions)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                             Func<IAsyncResult, TResult> endMethod,
-                                                             TArg1 arg1, TArg2 arg2, object state)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2> (Func<TArg1, TArg2, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                             Func<IAsyncResult, TResult> endMethod,
-                                                             TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                    Func<IAsyncResult, TResult> endMethod,
-                                                                    TArg1 arg1, TArg2 arg2, TArg3 arg3, object state)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               
-               [MonoLimitation(errorMsg)]
-               public Task<TResult> FromAsync<TArg1, TArg2, TArg3> (Func<TArg1, TArg2, TArg3, AsyncCallback, Object, IAsyncResult> beginMethod,
-                                                                    Func<IAsyncResult, TResult> endMethod,
-                                                                    TArg1 arg1, TArg2 arg2, TArg3 arg3, object state,
-                                                                    TaskCreationOptions creationOptions)
-               {
-                       throw new NotSupportedException (errorMsg);
-               }
-               #endregion
-               
-               public TaskScheduler Scheduler {
-                       get {
-                               return scheduler;
-                       }
-               }
-               
-               public TaskContinuationOptions ContinuationOptions {
-                       get {
-                               return contOptions;
-                       }
-               }
-               
-               public TaskCreationOptions CreationOptions {
-                       get {
-                               return options;
-                       }
-               }
-               
-               public CancellationToken CancellationToken {
-                       get {
-                               return token;
+                       if (tasks.Length == 0)
+                               throw new ArgumentException ("The tasks argument contains no tasks", "tasks");
+
+                       foreach (var ta in tasks) {
+                               if (ta == null)
+                                       throw new ArgumentException ("The tasks argument contains a null value", "tasks");
                        }
+
+                       if (continuationAction == null)
+                               throw new ArgumentNullException ("continuationAction");
+                       if (scheduler == null)
+                               throw new ArgumentNullException ("scheduler");
+
+                       const TaskContinuationOptions notAllowedOptions = 
+                               TaskContinuationOptions.NotOnRanToCompletion  |
+                               TaskContinuationOptions.NotOnFaulted |
+                               TaskContinuationOptions.NotOnCanceled |
+                               TaskContinuationOptions.OnlyOnRanToCompletion |
+                               TaskContinuationOptions.OnlyOnFaulted |
+                               TaskContinuationOptions.OnlyOnCanceled;
+
+                       if ((continuationOptions & notAllowedOptions) != 0)
+                               throw new ArgumentOutOfRangeException ("continuationOptions");
                }
        }
 }