/// <summary> /// An internal constructor used by the factory methods on task and its descendent(s). /// This variant does not capture the ExecutionContext; it is up to the caller to do that. /// </summary> /// <param name="action">An action to execute.</param> /// <param name="state">Optional state to pass to the action.</param> /// <param name="parent">Parent of Task.</param> /// <param name="cancellationToken">A CancellationToken for the task.</param> /// <param name="scheduler">A task scheduler under which the task will run.</param> /// <param name="creationOptions">Options to control its execution.</param> /// <param name="internalOptions">Internal options to control its execution</param> internal Task(Delegate action, object state, Task parent, CancellationToken cancellationToken, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions, TaskScheduler scheduler) { if (action == null) { throw new ArgumentNullException("action"); } if (ReferenceEquals(scheduler, null)) { throw new ArgumentNullException("scheduler"); } Contract.EndContractBlock(); // This is readonly, and so must be set in the constructor // Keep a link to your parent if: (A) You are attached, or (B) you are self-replicating. if ( ((creationOptions & TaskCreationOptions.AttachedToParent) != 0) || ((internalOptions & InternalTaskOptions.SelfReplicating) != 0) ) { _parent = parent; } _id = Interlocked.Increment(ref _lastId) - 1; _status = (int)TaskStatus.Created; if ( _parent != null && ((creationOptions & TaskCreationOptions.AttachedToParent) != 0) && ((_parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0) ) { _parent.AddNewChild(); } Action = action; State = state; ExecutingTaskScheduler = scheduler; _waitHandle = new ManualResetEventSlim(false); if ((creationOptions & ~(TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning | TaskCreationOptions.DenyChildAttach | TaskCreationOptions.HideScheduler | TaskCreationOptions.PreferFairness | TaskCreationOptions.RunContinuationsAsynchronously)) != 0) { throw new ArgumentOutOfRangeException("creationOptions"); } // Throw exception if the user specifies both LongRunning and SelfReplicating if (((creationOptions & TaskCreationOptions.LongRunning) != 0) && ((internalOptions & InternalTaskOptions.SelfReplicating) != 0)) { throw new InvalidOperationException("An attempt was made to create a LongRunning SelfReplicating task."); } if ((internalOptions & InternalTaskOptions.ContinuationTask) != 0) { // For continuation tasks or TaskCompletionSource.Tasks, begin life in the // WaitingForActivation state rather than the Created state. _status = (int)TaskStatus.WaitingForActivation; } _creationOptions = creationOptions; _internalOptions = internalOptions; // if we have a non-null cancellationToken, allocate the contingent properties to save it // we need to do this as the very last thing in the construction path, because the CT registration could modify m_stateFlags if (cancellationToken.CanBeCanceled) { AssignCancellationToken(cancellationToken, null, null); } }