コード例 #1
0
        // Token: 0x06004053 RID: 16467 RVA: 0x000EFBD4 File Offset: 0x000EDDD4
        internal override void Run(Task completedTask, bool bCanInlineContinuationTask)
        {
            TaskContinuationOptions options = this.m_options;
            bool flag = completedTask.IsRanToCompletion ? ((options & TaskContinuationOptions.NotOnRanToCompletion) == TaskContinuationOptions.None) : (completedTask.IsCanceled ? ((options & TaskContinuationOptions.NotOnCanceled) == TaskContinuationOptions.None) : ((options & TaskContinuationOptions.NotOnFaulted) == TaskContinuationOptions.None));
            Task task = this.m_task;

            if (flag)
            {
                if (!task.IsCanceled && AsyncCausalityTracer.LoggingOn)
                {
                    AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, task.Id, CausalityRelation.AssignDelegate);
                }
                task.m_taskScheduler = this.m_taskScheduler;
                if (bCanInlineContinuationTask && (options & TaskContinuationOptions.ExecuteSynchronously) != TaskContinuationOptions.None)
                {
                    TaskContinuation.InlineIfPossibleOrElseQueue(task, true);
                    return;
                }
                try
                {
                    task.ScheduleAndStart(true);
                    return;
                }
                catch (TaskSchedulerException)
                {
                    return;
                }
            }
            task.InternalCancel(false);
        }
コード例 #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)
        {
            Contract.Assert(completedTask != null);
            Contract.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.IsRanToCompletion ?
                (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 !FEATURE_PAL && !FEATURE_CORECLR
                //If the task was cancel before running (e.g a ContinueWhenAll with a cancelled caancelation token)
                //we will still flow it to ScheduleAndStart() were it will check the status before running
                //We check here to avoid faulty logs that contain a join event to an operation that was already set as completed.
                if (!continuationTask.IsCanceled && AsyncCausalityTracer.LoggingOn)
                {
                    // Log now that we are sure that this continuation is being ran
                    AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, continuationTask.Id, CausalityRelation.AssignDelegate);
                }
#endif
                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);
            }
        }
コード例 #3
0
ファイル: TaskContinuation.cs プロジェクト: kengey/corert
        /// <summary>Invokes the continuation for the target completion task.</summary>
        /// <param name="completedTask">The completed task.</param>
        /// <param name="canInlineContinuationTask">Whether the continuation can be inlined.</param>
        internal override void Run(Task completedTask, bool canInlineContinuationTask)
        {
            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 && AsyncCausalityTracer.LoggingOn)
                {
                    // Log now that we are sure that this continuation is being ran
                    AsyncCausalityTracer.TraceOperationRelation(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 (canInlineContinuationTask &&                                   // 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);
            }
        }
コード例 #4
0
        // Token: 0x06004044 RID: 16452 RVA: 0x000EF724 File Offset: 0x000ED924
        private bool TrySetFromTask(Task task, bool lookForOce)
        {
            if (AsyncCausalityTracer.LoggingOn)
            {
                AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, base.Id, CausalityRelation.Join);
            }
            bool result = false;

            switch (task.Status)
            {
            case TaskStatus.RanToCompletion:
            {
                Task <TResult> task2 = task as Task <TResult>;
                if (AsyncCausalityTracer.LoggingOn)
                {
                    AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, base.Id, AsyncCausalityStatus.Completed);
                }
                if (Task.s_asyncDebuggingEnabled)
                {
                    Task.RemoveFromActiveTasks(base.Id);
                }
                result = base.TrySetResult((task2 != null) ? task2.Result : default(TResult));
                break;
            }

            case TaskStatus.Canceled:
                result = base.TrySetCanceled(task.CancellationToken, task.GetCancellationExceptionDispatchInfo());
                break;

            case TaskStatus.Faulted:
            {
                ReadOnlyCollection <ExceptionDispatchInfo> exceptionDispatchInfos = task.GetExceptionDispatchInfos();
                ExceptionDispatchInfo      exceptionDispatchInfo;
                OperationCanceledException ex;
                if (lookForOce && exceptionDispatchInfos.Count > 0 && (exceptionDispatchInfo = exceptionDispatchInfos[0]) != null && (ex = (exceptionDispatchInfo.SourceException as OperationCanceledException)) != null)
                {
                    result = base.TrySetCanceled(ex.CancellationToken, exceptionDispatchInfo);
                }
                else
                {
                    result = base.TrySetException(exceptionDispatchInfos);
                }
                break;
            }
            }
            return(result);
        }
コード例 #5
0
        private bool TrySetFromTask(Task task, bool lookForOce)
        {
            if (AsyncCausalityTracer.LoggingOn)
            {
                AsyncCausalityTracer.TraceOperationRelation(CausalityTraceLevel.Important, this.Id, CausalityRelation.Join);
            }
            bool flag = false;

            switch (task.Status)
            {
            case TaskStatus.RanToCompletion:
                Task <TResult> task1 = task as Task <TResult>;
                if (AsyncCausalityTracer.LoggingOn)
                {
                    AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Id, AsyncCausalityStatus.Completed);
                }
                if (Task.s_asyncDebuggingEnabled)
                {
                    Task.RemoveFromActiveTasks(this.Id);
                }
                flag = this.TrySetResult(task1 != null ? task1.Result : default(TResult));
                break;

            case TaskStatus.Canceled:
                flag = this.TrySetCanceled(task.CancellationToken, (object)task.GetCancellationExceptionDispatchInfo());
                break;

            case TaskStatus.Faulted:
                ReadOnlyCollection <ExceptionDispatchInfo> exceptionDispatchInfos = task.GetExceptionDispatchInfos();
                ExceptionDispatchInfo      exceptionDispatchInfo;
                OperationCanceledException canceledException;
                flag = !lookForOce || exceptionDispatchInfos.Count <= 0 || ((exceptionDispatchInfo = exceptionDispatchInfos[0]) == null || (canceledException = exceptionDispatchInfo.SourceException as OperationCanceledException) == null) ? this.TrySetException((object)exceptionDispatchInfos) : this.TrySetCanceled(canceledException.CancellationToken, (object)exceptionDispatchInfo);
                break;
            }
            return(flag);
        }
コード例 #6
0
        /// <summary>Invokes the continuation for the target completion task.</summary>
        /// <param name="completedTask">The completed task.</param>
        /// <param name="canInlineContinuationTask">Whether the continuation can be inlined.</param>
        internal override void Run(Task completedTask, bool canInlineContinuationTask)
        {
            Debug.Assert(completedTask != null);
            Debug.Assert(completedTask.IsCompleted, "ContinuationTask.Run(): completedTask not completed");

            Task?continuationTask = m_task;

            Debug.Assert(continuationTask != null);
            m_task = null;

            // 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.
            if (isRightKind)
            {
                // If the task was cancel before running (e.g a ContinueWhenAll with a cancelled caancelation token)
                // we will still flow it to ScheduleAndStart() were it will check the status before running
                // We check here to avoid faulty logs that contain a join event to an operation that was already set as completed.
                if (!continuationTask.IsCanceled && AsyncCausalityTracer.LoggingOn)
                {
                    // Log now that we are sure that this continuation is being ran
                    AsyncCausalityTracer.TraceOperationRelation(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 (canInlineContinuationTask &&                                   // 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.
                    }
                }
            }
            else
            {
                // Otherwise, the final state of this task does not match the desired continuation activation criteria; cancel it to denote this.
                Task.ContingentProperties?cp = continuationTask.m_contingentProperties;  // no need to volatile read, as we only care about the token, which is only assignable at construction
                if (cp is null || cp.m_cancellationToken == default)
                {
                    // With no cancellation token, use an optimized path that doesn't need to account for concurrent completion.
                    // This is primarily valuable for continuations created with TaskContinuationOptions.NotOn* options, where
                    // we'll cancel the continuation if it's not needed.
                    continuationTask.InternalCancelContinueWithInitialState();
                }