#if NET_4_0 || MOBILE
-using System;
-using System.Threading;
-
namespace System.Threading.Tasks
{
-
public class TaskFactory
{
readonly TaskScheduler scheduler;
TaskCreationOptions creationOptions,
TaskScheduler scheduler)
{
- return StartNew<TResult> ((o) => function (), null, cancellationToken, creationOptions, 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 ContinueWhenAny (tasks, continuationAction, cancellationToken, continuationOptions, GetScheduler ());
}
- public Task ContinueWhenAny (Task[] tasks,
- Action<Task> continuationAction,
- CancellationToken cancellationToken,
- TaskContinuationOptions continuationOptions,
- TaskScheduler scheduler)
+ public Task ContinueWhenAny (Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- var ourTasks = (Task[])tasks.Clone ();
- AtomicBoolean trigger = new AtomicBoolean ();
- var commonContinuation = new TaskCompletionSource<object> ();
- Action<Task> continuationFunc = t => commonContinuation.SetResult (null);
-
- foreach (Task t in ourTasks) {
- Task cont = new Task (TaskActionInvoker.Create (continuationAction), null, cancellationToken, creationOptions, t);
- t.ContinueWithCore (cont, continuationOptions, scheduler, trigger.TrySet);
- cont.ContinueWith (continuationFunc);
- }
-
- return commonContinuation.Task;
+ 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,
TaskContinuationOptions continuationOptions,
TaskScheduler scheduler)
{
- var ourTasks = (Task[])tasks.Clone ();
- AtomicBoolean trigger = new AtomicBoolean ();
- TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult> ();
+ CheckContinueArguments (tasks, continuationFunction, continuationOptions, scheduler);
- foreach (Task t in ourTasks) {
- var cont = new Task (TaskActionInvoker.Create (continuationFunction), null, cancellationToken, creationOptions, t);
- t.ContinueWithCore (cont, continuationOptions, scheduler, trigger.TrySet);
- }
+ var cont = Task.WhenAnyCore (tasks).ContinueWith<TResult> (TaskActionInvoker.Create (continuationFunction, tasks), cancellationToken, continuationOptions, scheduler);
- return source.Task;
+ return cont;
}
public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult> (Task<TAntecedentResult>[] tasks,
public Task ContinueWhenAll (Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- var ourTasks = (Task[])tasks.Clone ();
- CountdownEvent evt = new CountdownEvent (ourTasks.Length);
- Task cont = new Task ((o) => continuationAction ((Task[])o), ourTasks, cancellationToken, creationOptions);
-
- foreach (Task t in ourTasks)
- 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;
}
CancellationToken cancellationToken,
TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
{
- var ourTasks = (Task[])tasks.Clone ();
- CountdownEvent evt = new CountdownEvent (ourTasks.Length);
- Task<TResult> cont = new Task<TResult> ((o) => continuationFunction ((Task[])o), ourTasks, cancellationToken, creationOptions);
-
- foreach (Task t in ourTasks)
- 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;
}
{
return scheduler ?? TaskScheduler.Current;
}
+
+ static void CheckContinueArguments (Task[] tasks, object continuationAction, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
+ {
+ if (tasks == null)
+ throw new ArgumentNullException ("tasks");
+
+ 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");
+ }
}
}
#endif