TaskFactory 源代码

using System;
using System.Collections.Generic;
using System.Security;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Diagnostics.Contracts;
 
namespace System.Threading.Tasks
{
    [HostProtection(Synchronization = true, ExternalThreading = true)]
    public class TaskFactory
    {
        private CancellationToken m_defaultCancellationToken;
        private TaskScheduler m_defaultScheduler;
        private TaskCreationOptions m_defaultCreationOptions;
        private TaskContinuationOptions m_defaultContinuationOptions;
 
        private TaskScheduler DefaultScheduler
        {
            get
            {
                if (m_defaultScheduler == null) return TaskScheduler.Current;
                else return m_defaultScheduler;
            }
        }
 
        private TaskScheduler GetDefaultScheduler(Task currTask)
        {
            if (m_defaultScheduler != null) return m_defaultScheduler;
            else if ((currTask != null)
                && ((currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
                )
                return currTask.ExecutingTaskScheduler;
            else return TaskScheduler.Default;
        }
 
        
        public TaskFactory()
            : this(default(CancellationToken), TaskCreationOptions.None, TaskContinuationOptions.None, null)
        {
        }
 
        
        public TaskFactory(CancellationToken cancellationToken)
            : this(cancellationToken, TaskCreationOptions.None, TaskContinuationOptions.None, null)
        {
        }
 
        
        public TaskFactory(TaskScheduler scheduler) 
            : this(default(CancellationToken), TaskCreationOptions.None, TaskContinuationOptions.None, scheduler)
        {
        }
 
         
        public TaskFactory(TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions)
            : this(default(CancellationToken), creationOptions, continuationOptions, null)
        {
        }
 
        
        public TaskFactory(CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            CheckMultiTaskContinuationOptions(continuationOptions);
            CheckCreationOptions(creationOptions);
 
            m_defaultCancellationToken = cancellationToken;
            m_defaultScheduler = scheduler;
            m_defaultCreationOptions = creationOptions;
            m_defaultContinuationOptions = continuationOptions;
        }
 
        [ContractArgumentValidatorAttribute]
        internal static void CheckCreationOptions(TaskCreationOptions creationOptions)
        {
            // Check for validity of options
            if ((creationOptions &
                    ~(TaskCreationOptions.AttachedToParent |
                      TaskCreationOptions.DenyChildAttach |
                      TaskCreationOptions.HideScheduler |
                      TaskCreationOptions.LongRunning |
                      TaskCreationOptions.PreferFairness |
                      TaskCreationOptions.RunContinuationsAsynchronously)) != 0)
            {
                throw new ArgumentOutOfRangeException("creationOptions");
            }
            Contract.EndContractBlock();
        }
 
        
        public CancellationToken CancellationToken { get { return m_defaultCancellationToken; } }
        
        public TaskScheduler Scheduler { get { return m_defaultScheduler; } }
        
        public TaskCreationOptions CreationOptions { get { return m_defaultCreationOptions; } 
        
        public TaskContinuationOptions ContinuationOptions { get { return m_defaultContinuationOptions; } }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task StartNew(Action action)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask),
                m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task StartNew(Action action, CancellationToken cancellationToken)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task.InternalStartNew(currTask, action, null, cancellationToken, GetDefaultScheduler(currTask),
                m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task StartNew(Action action, TaskCreationOptions creationOptions)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task.InternalStartNew(currTask, action, null, m_defaultCancellationToken, GetDefaultScheduler(currTask), creationOptions,
                InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]           
        public Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            return Task.InternalStartNew(
                Task.InternalCurrentIfAttached(creationOptions), action, null, cancellationToken, scheduler, creationOptions,
                InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)] 
        internal Task StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            return Task.InternalStartNew(
                Task.InternalCurrentIfAttached(creationOptions), action, null, cancellationToken, scheduler, creationOptions, internalOptions, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task StartNew(Action<Object> action, Object state)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
                m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)] 
        public Task StartNew(Action<Object> action, Object state, CancellationToken cancellationToken)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task.InternalStartNew(currTask, action, state, cancellationToken, GetDefaultScheduler(currTask),
                m_defaultCreationOptions, InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task StartNew(Action<Object> action, Object state, TaskCreationOptions creationOptions)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task.InternalStartNew(currTask, action, state, m_defaultCancellationToken, GetDefaultScheduler(currTask),
                creationOptions, InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task StartNew(Action<Object> action, Object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            return Task.InternalStartNew(
                Task.InternalCurrentIfAttached(creationOptions), action, state, cancellationToken, scheduler,
                creationOptions, InternalTaskOptions.None, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> StartNew<TResult>(Func<TResult> function)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken,
                m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> StartNew<TResult>(Func<TResult> function, CancellationToken cancellationToken)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;

            Task currTask = Task.InternalCurrent;
            return Task<TResult>.StartNew(currTask, function, cancellationToken,
                m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
        }
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> StartNew<TResult>(Func<TResult> function, TaskCreationOptions creationOptions)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            Task currTask = Task.InternalCurrent;
            return Task<TResult>.StartNew(currTask, function, m_defaultCancellationToken,
                creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]           
        public Task<TResult> StartNew<TResult>(Func<TResult> function, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return Task<TResult>.StartNew(
                Task.InternalCurrentIfAttached(creationOptions), function, cancellationToken,
                creationOptions, InternalTaskOptions.None, scheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            Task currTask = Task.InternalCurrent;
            return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
                m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state, CancellationToken cancellationToken)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            Task currTask = Task.InternalCurrent;
            return Task<TResult>.StartNew(currTask, function, state, cancellationToken,
                m_defaultCreationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state, TaskCreationOptions creationOptions)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            Task currTask = Task.InternalCurrent;
            return Task<TResult>.StartNew(currTask, function, state, m_defaultCancellationToken,
                creationOptions, InternalTaskOptions.None, GetDefaultScheduler(currTask), ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> StartNew<TResult>(Func<Object, TResult> function, Object state, CancellationToken cancellationToken,
            TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return Task<TResult>.StartNew(
                Task.InternalCurrentIfAttached(creationOptions), function, state, cancellationToken,
                creationOptions, InternalTaskOptions.None, scheduler, ref stackMark);
        }
 
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task FromAsync(IAsyncResult asyncResult,Action<IAsyncResult> endMethod)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return FromAsync(asyncResult, endMethod, m_defaultCreationOptions, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task FromAsync(IAsyncResult asyncResult,Action<IAsyncResult> endMethod,TaskCreationOptions creationOptions)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return FromAsync(asyncResult, endMethod, creationOptions, DefaultScheduler, ref stackMark);
        }
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task FromAsync(IAsyncResult asyncResult,Action<IAsyncResult> endMethod,TaskCreationOptions creationOptions,TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return FromAsync(asyncResult, endMethod, creationOptions, scheduler, ref stackMark);
        }
 
        private Task FromAsync(IAsyncResult asyncResult,Action<IAsyncResult> endMethod,TaskCreationOptions creationOptions,TaskScheduler scheduler,ref StackCrawlMark stackMark)
        {
            return TaskFactory<VoidTaskResult>.FromAsyncImpl(asyncResult, null, endMethod, creationOptions, scheduler, ref stackMark);
        }
 
        
        public Task FromAsync(Func<AsyncCallback, object, IAsyncResult> beginMethod,Action<IAsyncResult> endMethod,object state)
        {
            return FromAsync(beginMethod, endMethod, state, m_defaultCreationOptions);
        }
 
        
        public Task FromAsync(
            Func<AsyncCallback, object, IAsyncResult> beginMethod,
            Action<IAsyncResult> endMethod, object state, TaskCreationOptions creationOptions)
        {
            return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, state, creationOptions);
        }
 
        
        public Task FromAsync<TArg1>(
            Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
            Action<IAsyncResult> endMethod,TArg1 arg1,object state)
        {
            return FromAsync(beginMethod, endMethod, arg1, state, m_defaultCreationOptions);
        }
 
        
        public Task FromAsync<TArg1>(
            Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
            Action<IAsyncResult> endMethod,
            TArg1 arg1, object state, TaskCreationOptions creationOptions)
        {
            return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, arg1, state, creationOptions);
        }
 
        
        public Task FromAsync<TArg1, TArg2>(
            Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
            Action<IAsyncResult> endMethod,
            TArg1 arg1, TArg2 arg2, object state)
        {
            return FromAsync(beginMethod, endMethod, arg1, arg2, state, m_defaultCreationOptions);
        }
 
        
        public Task FromAsync<TArg1, TArg2>(
            Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
            Action<IAsyncResult> endMethod,
            TArg1 arg1, TArg2 arg2, object state, TaskCreationOptions creationOptions)
        {
            return TaskFactory<VoidTaskResult>.FromAsyncImpl(beginMethod, null, endMethod, arg1, arg2, state, creationOptions);
        }
 
        
        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)
        {
            return FromAsync(beginMethod, endMethod, arg1, arg2, arg3, state, m_defaultCreationOptions);
        }
 
        
        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)
        {
            return TaskFactory<VoidTaskResult>.FromAsyncImpl<TArg1, TArg2, TArg3>(beginMethod, null, endMethod, arg1, arg2, arg3, state, creationOptions);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task<TResult> FromAsync<TResult>(IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.FromAsyncImpl(asyncResult, endMethod, null, m_defaultCreationOptions, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> FromAsync<TResult>(
            IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.FromAsyncImpl(asyncResult, endMethod, null, creationOptions, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task<TResult> FromAsync<TResult>(
            IAsyncResult asyncResult, Func<IAsyncResult, TResult> endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.FromAsyncImpl(asyncResult, endMethod, null, creationOptions, scheduler, ref stackMark);
        }
 
        
        public Task<TResult> FromAsync<TResult>(
            Func<AsyncCallback, object, IAsyncResult> beginMethod,
            Func<IAsyncResult, TResult> endMethod, object state)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, state, m_defaultCreationOptions);
        }
 
        
        public Task<TResult> FromAsync<TResult>(
            Func<AsyncCallback, object, IAsyncResult> beginMethod,
            Func<IAsyncResult, TResult> endMethod, object state, TaskCreationOptions creationOptions)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, state, creationOptions);
        }
 
        
        public Task<TResult> FromAsync<TArg1, TResult>(
            Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
            Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object state)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, state, m_defaultCreationOptions);
        }
 
        
        public Task<TResult> FromAsync<TArg1, TResult>(Func<TArg1, AsyncCallback, object, IAsyncResult> beginMethod,
            Func<IAsyncResult, TResult> endMethod, TArg1 arg1, object state, TaskCreationOptions creationOptions)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, state, creationOptions);
        }
 
        
        public Task<TResult> FromAsync<TArg1, TArg2, TResult>(Func<TArg1, TArg2, AsyncCallback, object, IAsyncResult> beginMethod,
            Func<IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, m_defaultCreationOptions);
        }
 
        
        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)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, state, creationOptions);
        }
 
        
        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)
        {
            return TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, m_defaultCreationOptions);
        }
 
        
        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 TaskFactory<TResult>.FromAsyncImpl(beginMethod, endMethod, null, arg1, arg2, arg3, state, creationOptions);
        }
 
       
        internal static void CheckFromAsyncOptions(TaskCreationOptions creationOptions, bool hasBeginMethod)
        {
            if (hasBeginMethod)
            {
                if ((creationOptions & TaskCreationOptions.LongRunning) != 0)
                    throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_LongRunning"));
                if ((creationOptions & TaskCreationOptions.PreferFairness) != 0)
                    throw new ArgumentOutOfRangeException("creationOptions", Environment.GetResourceString("Task_FromAsync_PreferFairness"));
            }
 
            // Check for general validity of options
            if ((creationOptions &
                    ~(TaskCreationOptions.AttachedToParent |
                      TaskCreationOptions.DenyChildAttach |
                      TaskCreationOptions.HideScheduler |
                      TaskCreationOptions.PreferFairness |
                      TaskCreationOptions.LongRunning)) != 0)
            {
                throw new ArgumentOutOfRangeException("creationOptions");
            }
        }
 
 
        private sealed class CompleteOnCountdownPromise : Task<Task[]>, ITaskCompletionAction
        {
            private readonly Task[] _tasks;
            private int _count;
 
            internal CompleteOnCountdownPromise(Task[] tasksCopy) : base()
            {
                Contract.Requires((tasksCopy != null) && (tasksCopy.Length > 0), "Expected non-null task array with at least one element in it");
                _tasks = tasksCopy;
                _count = tasksCopy.Length;
 
                if (AsyncCausalityTracer.LoggingOn)
                    AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAll", 0);
 
                if (Task.s_asyncDebuggingEnabled)
                {
                    AddToActiveTasks(this);
                }
            }
 
            public void Invoke(Task completingTask)
            {
                if (AsyncCausalityTracer.LoggingOn)
                    AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Join);
 
                if (completingTask.IsWaitNotificationEnabled) this.SetNotificationForWaitCompletion(enabled: true);
                if (Interlocked.Decrement(ref _count) == 0)
                {
                    if (AsyncCausalityTracer.LoggingOn)
                        AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
 
                    if (Task.s_asyncDebuggingEnabled)
                    {
                        RemoveFromActiveTasks(this.Id);
                    }
 
                    TrySetResult(_tasks);
                }
                Contract.Assert(_count >= 0, "Count should never go below 0");
            }
 
            
            internal override bool ShouldNotifyDebuggerOfWaitCompletion
            {
                get
                {
                    return
                        base.ShouldNotifyDebuggerOfWaitCompletion &&
                        Task.AnyTaskRequiresNotifyDebuggerOfWaitCompletion(_tasks);
                }
            }
        }
 
        
        internal static Task<Task[]> CommonCWAllLogic(Task[] tasksCopy)
        {
            Contract.Requires(tasksCopy != null);
 
            CompleteOnCountdownPromise promise = new CompleteOnCountdownPromise(tasksCopy);
 
            for (int i = 0; i < tasksCopy.Length; i++)
            {
                if (tasksCopy[i].IsCompleted) promise.Invoke(tasksCopy[i]); // Short-circuit the completion action, if possible
                else tasksCopy[i].AddCompletionAction(promise); // simple completion action
            }
 
            return promise;
        }
 
 
        private sealed class CompleteOnCountdownPromise<T> : Task<Task<T>[]>, ITaskCompletionAction
        {
            private readonly Task<T>[] _tasks;
            private int _count;
 
            internal CompleteOnCountdownPromise(Task<T>[] tasksCopy) : base()
            {
                Contract.Requires((tasksCopy != null) && (tasksCopy.Length > 0), "Expected non-null task array with at least one element in it");
                _tasks = tasksCopy;
                _count = tasksCopy.Length;
 
                if (AsyncCausalityTracer.LoggingOn)
                    AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAll<>", 0);
 
                if (Task.s_asyncDebuggingEnabled)
                {
                    AddToActiveTasks(this);
                }
            }
 
            public void Invoke(Task completingTask)
            {
                if (AsyncCausalityTracer.LoggingOn)
                    AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Join);
 
                if (completingTask.IsWaitNotificationEnabled) this.SetNotificationForWaitCompletion(enabled: true);
                if (Interlocked.Decrement(ref _count) == 0)
                {
                    if (AsyncCausalityTracer.LoggingOn)
                        AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
 
                    if (Task.s_asyncDebuggingEnabled)
                    {
                        RemoveFromActiveTasks(this.Id);
                    }
 
                    TrySetResult(_tasks);
                }
                Contract.Assert(_count >= 0, "Count should never go below 0");
            }
 
            
            internal override bool ShouldNotifyDebuggerOfWaitCompletion
            {
                get
                {
                    return
                        base.ShouldNotifyDebuggerOfWaitCompletion &&
                        Task.AnyTaskRequiresNotifyDebuggerOfWaitCompletion(_tasks);
                }
            }
        }
 
 
        internal static Task<Task<T>[]> CommonCWAllLogic<T>(Task<T>[] tasksCopy)
        {
            Contract.Requires(tasksCopy != null);
 
            CompleteOnCountdownPromise<T> promise = new CompleteOnCountdownPromise<T>(tasksCopy);
 
            for (int i = 0; i < tasksCopy.Length; i++)
            {
                if (tasksCopy[i].IsCompleted) promise.Invoke(tasksCopy[i]); 
                else tasksCopy[i].AddCompletionAction(promise); 
            }
 
            return promise;
        }
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, TaskContinuationOptions continuationOptions)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task ContinueWhenAll(Task[] tasks, Action<Task[]> continuationAction, CancellationToken cancellationToken,
            TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,CancellationToken cancellationToken)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,TaskContinuationOptions continuationOptions)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAll<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>[]> continuationAction,CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, TaskContinuationOptions continuationOptions)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAll<TResult>(Task[] tasks, Func<Task[], TResult> continuationFunction, CancellationToken cancellationToken,TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,CancellationToken cancellationToken)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,TaskContinuationOptions continuationOptions)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>[], TResult> continuationFunction,CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
        

        internal sealed class CompleteOnInvokePromise : Task<Task>, ITaskCompletionAction
        {
            private IList<Task> _tasks; 
            private int m_firstTaskAlreadyCompleted;
 
            public CompleteOnInvokePromise(IList<Task> tasks) : base()
            {
                Contract.Requires(tasks != null, "Expected non-null collection of tasks");
                _tasks = tasks;
                
                if (AsyncCausalityTracer.LoggingOn)
                    AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAny", 0);
 
                if (Task.s_asyncDebuggingEnabled)
                {
                    AddToActiveTasks(this);
                }
            }
 
            public void Invoke(Task completingTask)
            {
                if (Interlocked.CompareExchange(ref m_firstTaskAlreadyCompleted, 1, 0) == 0)
                {
                    if (AsyncCausalityTracer.LoggingOn)
                    {
                        AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Choice);
                        AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
                    }
 
                    if (Task.s_asyncDebuggingEnabled)
                    {
                        RemoveFromActiveTasks(this.Id);
                    }
 
                    bool success = TrySetResult(completingTask);
                    Contract.Assert(success, "Only one task should have gotten to this point, and thus this must be successful.");
 
                    var tasks = _tasks;
                    int numTasks = tasks.Count;
                    for (int i = 0; i < numTasks; i++)
                    {
                        var task = tasks[i];
                        if (task != null &&!task.IsCompleted) task.RemoveContinuation(this);
                    }
                    _tasks = null;
 
                }
            }
        }

        internal static Task<Task> CommonCWAnyLogic(IList<Task> tasks)
        {
            Contract.Requires(tasks != null);
 
            var promise = new CompleteOnInvokePromise(tasks);
 
            bool checkArgsOnly = false;
            int numTasks = tasks.Count;
            for(int i=0; i<numTasks; i++)
            {
                var task = tasks[i];
                if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
 
                if (checkArgsOnly) continue;
 
                if (promise.IsCompleted)
                {
                    checkArgsOnly = true;
                }
                else if (task.IsCompleted)
                {
                    promise.Invoke(task);
                    checkArgsOnly = true;
                }
                else task.AddCompletionAction(promise);
            }
 
            return promise;
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        

        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, TaskContinuationOptions continuationOptions)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task ContinueWhenAny(Task[] tasks, Action<Task> continuationAction, CancellationToken cancellationToken,
            TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
       
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]           
        public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null,continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TResult>(Task[] tasks, Func<Task, TResult> continuationFunction, CancellationToken cancellationToken,TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction)
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,CancellationToken cancellationToken)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null,  m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,TaskContinuationOptions continuationOptions)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(Task<TAntecedentResult>[] tasks, Func<Task<TAntecedentResult>, TResult> continuationFunction,CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationFunction == null) throw new ArgumentNullException("continuationFunction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]             
        public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,CancellationToken cancellationToken)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, m_defaultContinuationOptions, cancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,TaskContinuationOptions continuationOptions)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, m_defaultCancellationToken, DefaultScheduler, ref stackMark);
        }
 
        
        [MethodImplAttribute(MethodImplOptions.NoInlining)]            
        public Task ContinueWhenAny<TAntecedentResult>(Task<TAntecedentResult>[] tasks, Action<Task<TAntecedentResult>> continuationAction,CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler)
        {
            if (continuationAction == null) throw new ArgumentNullException("continuationAction");
            Contract.EndContractBlock();
 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            return TaskFactory<VoidTaskResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, null, continuationAction, continuationOptions, cancellationToken, scheduler, ref stackMark);
        }
 
        internal static Task[] CheckMultiContinuationTasksAndCopy(Task[] tasks)
        {
            if (tasks == null)
                throw new ArgumentNullException("tasks");
            if (tasks.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
            Contract.EndContractBlock();
 
            Task[] tasksCopy = new Task[tasks.Length];
            for (int i = 0; i < tasks.Length; i++)
            {
                tasksCopy[i] = tasks[i];
 
                if (tasksCopy[i] == null)
                    throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
            }
 
            return tasksCopy;
        }
 
        internal static Task<TResult>[] CheckMultiContinuationTasksAndCopy<TResult>(Task<TResult>[] tasks)
        {
            if (tasks == null)
                throw new ArgumentNullException("tasks");
            if (tasks.Length == 0)
                throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), "tasks");
            Contract.EndContractBlock();
 
            Task<TResult>[] tasksCopy = new Task<TResult>[tasks.Length];
            for (int i = 0; i < tasks.Length; i++)
            {
                tasksCopy[i] = tasks[i];
 
                if (tasksCopy[i] == null)
                    throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), "tasks");
            }
 
            return tasksCopy;
        }
 

        [ContractArgumentValidatorAttribute]
        internal static void CheckMultiTaskContinuationOptions(TaskContinuationOptions continuationOptions)
        {
            // Construct a mask to check for illegal options
            const TaskContinuationOptions NotOnAny = TaskContinuationOptions.NotOnCanceled |
                                               TaskContinuationOptions.NotOnFaulted |
                                               TaskContinuationOptions.NotOnRanToCompletion;
 
            // Check that LongRunning and ExecuteSynchronously are not specified together
            const TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning;
            if ((continuationOptions & illegalMask) == illegalMask)
            {
                throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_ContinueWith_ESandLR"));
            }
 
            // Check that no nonsensical options are specified.
            if ((continuationOptions & ~(
                TaskContinuationOptions.LongRunning |
                TaskContinuationOptions.PreferFairness |
                TaskContinuationOptions.AttachedToParent |
                TaskContinuationOptions.DenyChildAttach |
                TaskContinuationOptions.HideScheduler |
                TaskContinuationOptions.LazyCancellation |
                NotOnAny |
                TaskContinuationOptions.ExecuteSynchronously)) != 0)
            {
                throw new ArgumentOutOfRangeException("continuationOptions");
            }
 
            // Check that no "fire" options are specified.
            if ((continuationOptions & NotOnAny) != 0)
                throw new ArgumentOutOfRangeException("continuationOptions", Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions"));
            Contract.EndContractBlock();
        }
    }
 
}

 

posted @ 2016-09-07 11:42  茗::流  阅读(219)  评论(0)    收藏  举报
如有雷同,纯属参考。如有侵犯你的版权,请联系我。