Ejemplo n.º 1
0
        internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued, object threadStatics)
        {
            TaskScheduler executingTaskScheduler = task.ExecutingTaskScheduler;

            if ((executingTaskScheduler != this) && (executingTaskScheduler != null))
            {
                return(executingTaskScheduler.TryRunInline(task, taskWasPreviouslyQueued));
            }
            if (((executingTaskScheduler == null) || (task.m_action == null)) || ((task.IsDelegateInvoked || task.IsCanceled) || !Task.CurrentStackGuard.TryBeginInliningScope()))
            {
                return(false);
            }
            bool flag = false;

            try
            {
                flag = this.TryExecuteTaskInline(task, taskWasPreviouslyQueued);
            }
            finally
            {
                Task.CurrentStackGuard.EndInliningScope();
            }
            if ((flag && !task.IsDelegateInvoked) && !task.IsCanceled)
            {
                throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline"));
            }
            return(flag);
        }
        /// <summary>
        /// Attempts to execute the target task synchronously.
        /// </summary>
        /// <param name="task">The task to run.</param>
        /// <param name="taskWasPreviouslyQueued">True if the task may have been previously queued,
        /// false if the task was absolutely not previously queued.</param>
        /// <param name="threadStatics">The state retrieved from GetThreadStatics</param>
        /// <returns>True if it ran, false otherwise.</returns>
        // [SecuritySafeCritical]
        internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued, object threadStatics)
        {
            // Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null).
            // Do not inline TaskCompletionSource-style (a.k.a. "promise") tasks.
            // No need to attempt inlining if the task body was already run (i.e. either TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bits set)
            TaskScheduler ets = task.ExecutingTaskScheduler;

            // Delegate cross-scheduler inlining requests to target scheduler
            if (ets != this && ets != null)
            {
                return(ets.TryRunInline(task, taskWasPreviouslyQueued));
            }

            if ((ets == null) ||
                (task.m_action == null) ||
                task.IsDelegateInvoked ||
                task.IsCanceled)
            {
                return(false);
            }

            // Task class will still call into TaskScheduler.TryRunInline rather than TryExecuteTaskInline() so that
            // 1) we can adjust the return code from TryExecuteTaskInline in case a buggy custom scheduler lies to us
            // 2) we maintain a mechanism for the TLS lookup optimization that we used to have for the ConcRT scheduler (will potentially introduce the same for TP)
            bool bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);

            // If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set
            // Otherwise the scheduler is buggy
            if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled))
            {
                throw new InvalidOperationException(Strings.TaskScheduler_InconsistentStateAfterTryExecuteTaskInline);
            }

            return(bInlined);
        }
Ejemplo n.º 3
0
        internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued)
        {
            TaskScheduler executingTaskScheduler = task.ExecutingTaskScheduler;

            if (executingTaskScheduler != this && executingTaskScheduler != null)
            {
                return(executingTaskScheduler.TryRunInline(task, taskWasPreviouslyQueued));
            }
            StackGuard currentStackGuard;

            if (executingTaskScheduler == null || task.m_action == null || task.IsDelegateInvoked || task.IsCanceled || !(currentStackGuard = Task.CurrentStackGuard).TryBeginInliningScope())
            {
                return(false);
            }
            bool flag = false;

            try
            {
                task.FireTaskScheduledIfNeeded(this);
                flag = this.TryExecuteTaskInline(task, taskWasPreviouslyQueued);
            }
            finally
            {
                currentStackGuard.EndInliningScope();
            }
            if (flag && !task.IsDelegateInvoked && !task.IsCanceled)
            {
                throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline"));
            }
            return(flag);
        }