-#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)
{
}
{
}
- 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;
}
#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
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");
}
}
}