// 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); }
/// <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); } }
/// <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); } }
// 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); }
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); }
/// <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(); }