Beispiel #1
0
 /// <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);
     }
 }