示例#1
0
        /// <summary>Initializes a new continuation.</summary>
        /// <param name="task">The task to be activated.</param>
        /// <param name="options">The continuation options.</param>
        /// <param name="scheduler">The scheduler to use for the continuation.</param>
        internal StandardTaskContinuation(Task task, TaskContinuationOptions options, TaskScheduler scheduler)
        {
            Debug.Assert(task != null, "TaskContinuation ctor: task is null");
            Debug.Assert(scheduler != null, "TaskContinuation ctor: scheduler is null");
            m_task = task;
            m_options = options;
            m_taskScheduler = scheduler;

            if (DebuggerSupport.LoggingOn)
                DebuggerSupport.TraceOperationCreation(CausalityTraceLevel.Required, m_task, "Task.ContinueWith: " + task.m_action, 0);
            DebuggerSupport.AddToActiveTasks(m_task);
        }
示例#2
0
        /// <summary>Invokes the continuation for the target completion task.</summary>
        /// <param name="completedTask">The completed task.</param>
        /// <param name="bCanInlineContinuationTask">Whether the continuation can be inlined.</param>
        internal override void Run(Task completedTask, bool bCanInlineContinuationTask)
        {
            Debug.Assert(completedTask != null);
            Debug.Assert(completedTask.IsCompleted, "ContinuationTask.Run(): completedTask not completed");

            // Check if the completion status of the task works with the desired
            // activation criteria of the TaskContinuationOptions.
            TaskContinuationOptions options = m_options;
            bool isRightKind =
                completedTask.IsCompletedSuccessfully ?
                (options & TaskContinuationOptions.NotOnRanToCompletion) == 0 :
                (completedTask.IsCanceled ?
                 (options & TaskContinuationOptions.NotOnCanceled) == 0 :
                 (options & TaskContinuationOptions.NotOnFaulted) == 0);

            // If the completion status is allowed, run the continuation.
            Task continuationTask = m_task;

            if (isRightKind)
            {
                if (!continuationTask.IsCanceled && DebuggerSupport.LoggingOn)
                {
                    // Log now that we are sure that this continuation is being ran
                    DebuggerSupport.TraceOperationRelation(CausalityTraceLevel.Important, continuationTask, CausalityRelation.AssignDelegate);
                }

                continuationTask.m_taskScheduler = m_taskScheduler;

                // Either run directly or just queue it up for execution, depending
                // on whether synchronous or asynchronous execution is wanted.
                if (bCanInlineContinuationTask &&                                  // inlining is allowed by the caller
                    (options & TaskContinuationOptions.ExecuteSynchronously) != 0) // synchronous execution was requested by the continuation's creator
                {
                    InlineIfPossibleOrElseQueue(continuationTask, needsProtection: true);
                }
                else
                {
                    try { continuationTask.ScheduleAndStart(needsProtection: true); }
                    catch (TaskSchedulerException)
                    {
                        // No further action is necessary -- ScheduleAndStart() already transitioned the
                        // task to faulted.  But we want to make sure that no exception is thrown from here.
                    }
                }
            }
            // Otherwise, the final state of this task does not match the desired
            // continuation activation criteria; cancel it to denote this.
            else
            {
                continuationTask.InternalCancel(false);
            }
        }