Inheritance: System.Exception
Ejemplo n.º 1
0
 protected static void InlineIfPossibleOrElseQueue(Task task, bool needsProtection)
 {
     if (needsProtection)
     {
         if (!task.MarkStarted())
         {
             return;
         }
     }
     else
     {
         task.m_stateFlags |= 65536;
     }
     try
     {
         if (task.m_taskScheduler.TryRunInline(task, false))
         {
             return;
         }
         task.m_taskScheduler.InternalQueueTask(task);
     }
     catch (Exception ex)
     {
         if (ex is ThreadAbortException && (task.m_stateFlags & 134217728) != 0)
         {
             return;
         }
         TaskSchedulerException schedulerException = new TaskSchedulerException(ex);
         task.AddException((object)schedulerException);
         task.Finish(false);
     }
 }
Ejemplo n.º 2
0
        internal bool InternalStart(TaskScheduler scheduler, bool inline, bool throwSchedulerExceptions)
        {
            ExecutingTaskScheduler = scheduler;
            var result = Interlocked.CompareExchange(ref _status, (int)TaskStatus.WaitingForActivation, (int)TaskStatus.Created);

            if (result != (int)TaskStatus.Created && result != (int)TaskStatus.WaitingForActivation)
            {
                return(false);
            }

            var didInline = false;

            try
            {
                if (inline)
                {
                    // Should I worry about this task being a continuation?
                    // WaitAntecedent(CancellationToken);
                    didInline = scheduler.InternalTryExecuteTaskInline(this, IsScheduled);
                }

                if (!didInline)
                {
                    scheduler.QueueTask(this);
                    Interlocked.CompareExchange(ref _status, (int)TaskStatus.WaitingToRun, (int)TaskStatus.WaitingForActivation);
                }
                else
                {
                    PrivateWait(CancellationToken, false);
                }
            }
            catch (ThreadAbortException exception)
            {
                if (didInline)
                {
                    return(true);
                }

                AddException(exception);
                FinishThreadAbortedTask(true, false);
            }
            catch (Exception exception)
            {
                var taskSchedulerException = new TaskSchedulerException(exception);
                RecordException(taskSchedulerException);
                if (throwSchedulerExceptions)
                {
                    throw taskSchedulerException;
                }
            }

            return(true);
        }
Ejemplo n.º 3
0
 private void RecordException(TaskSchedulerException taskSchedulerException)
 {
     AddException(taskSchedulerException);
     Finish(false);
     if ((_internalOptions & InternalTaskOptions.ContinuationTask) != 0)
     {
         return;
     }
     if (_exceptionsHolder != null)
     {
         Contract.Assert(_exceptionsHolder.ContainsFaultList, "Expected _exceptionsHolder to have faults recorded.");
         _exceptionsHolder.MarkAsHandled(false);
     }
     else
     {
         Contract.Assert(false, "Expected _exceptionsHolder to exist.");
     }
 }
Ejemplo n.º 4
0
        protected static void InlineIfPossibleOrElseQueue(Task task, bool needsProtection)
        {
            Contract.Requires(task != null);
            Contract.Assert(task.m_taskScheduler != null);

            // Set the TASK_STATE_STARTED flag.  This only needs to be done
            // if the task may be canceled or if someone else has a reference to it
            // that may try to execute it.
            if (needsProtection)
            {
                if (!task.MarkStarted())
                {
                    return; // task has been previously started or canceled.  Stop processing.
                }
            }
            else
            {
                task.m_stateFlags |= Task.TASK_STATE_STARTED;
            }

            // Try to inline it but queue if we can't
            try
            {
                if (!task.m_taskScheduler.TryRunInline(task, taskWasPreviouslyQueued: false))
                {
                    task.m_taskScheduler.InternalQueueTask(task);
                }
            }
            catch (Exception e)
            {
                // Either TryRunInline() or QueueTask() threw an exception. Record the exception, marking the task as Faulted.
                // However if it was a ThreadAbortException coming from TryRunInline we need to skip here,
                // because it would already have been handled in Task.Execute()
                if (!(e is ThreadAbortException &&
                      (task.m_stateFlags & Task.TASK_STATE_THREAD_WAS_ABORTED) != 0))    // this ensures TAEs from QueueTask will be wrapped in TSE
                {
                    TaskSchedulerException tse = new TaskSchedulerException(e);
                    task.AddException(tse);
                    task.Finish(false);
                }

                // Don't re-throw.
            }
        }
Ejemplo n.º 5
0
        internal bool InternalCancel(bool cancelNonExecutingOnly)
        {
            Contract.Requires((_internalOptions & InternalTaskOptions.PromiseTask) == 0, "Task.InternalCancel() did not expect promise-style task");

            var cancelSucceeded = false;
            TaskSchedulerException taskSchedulerException = null;

            RecordInternalCancellationRequest();

            var status = Thread.VolatileRead(ref _status);

            if (status <= (int)TaskStatus.WaitingToRun)
            {
                // Note: status may advance to TaskStatus.Running or even TaskStatus.RanToCompletion during the execution of this method
                var scheduler = Scheduler;
                var requiresAtomicStartTransition = scheduler.RequiresAtomicStartTransition;
                var popSucceeded = scheduler.InernalTryDequeue(this, ref requiresAtomicStartTransition);
                if (!popSucceeded && requiresAtomicStartTransition)
                {
                    status          = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.Created);
                    cancelSucceeded = status == (int)TaskStatus.Created;
                    status          = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.WaitingForActivation);
                    cancelSucceeded = cancelSucceeded || status == (int)TaskStatus.WaitingForActivation;
                    status          = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.WaitingToRun);
                    cancelSucceeded = cancelSucceeded || status == (int)TaskStatus.WaitingToRun;
                }
            }
            if (Thread.VolatileRead(ref _status) >= (int)TaskStatus.Running && !cancelNonExecutingOnly)
            {
                // We are going to pretend that the cancel call came after the task finished running, but we may still set to cancel on TaskStatus.WaitingForChildrenToComplete
                status          = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.WaitingForChildrenToComplete);
                cancelSucceeded = cancelSucceeded || status == (int)TaskStatus.WaitingForChildrenToComplete;
            }
            if (cancelSucceeded)
            {
                MarkCompleted();
                FinishStageThree();
            }
            if (taskSchedulerException != null)
            {
                throw taskSchedulerException;
            }
            return(cancelSucceeded);
        }
Ejemplo n.º 6
0
        public static void RunTaskSchedulerExceptionTests()
        {
            TaskSchedulerException tse = null;

            tse = new TaskSchedulerException();
            Assert.Null(tse.InnerException); // , "RunTaskSchedulerExceptionTests:  Expected InnerException==null after empty ctor")

            InvalidOperationException ioe = new InvalidOperationException();
            tse = new TaskSchedulerException(ioe);
            Assert.True(tse.InnerException == ioe, "RunTaskSchedulerExceptionTests:  Expected InnerException == ioe passed to ctor(ex)");

            string message = "my exception message";
            tse = new TaskSchedulerException(message);
            Assert.Null(tse.InnerException); // , "RunTaskSchedulerExceptionTests:  Expected InnerException==null after ctor(string)")
            Assert.True(tse.Message.Equals(message), "RunTaskSchedulerExceptionTests:  Expected Message = message passed to ctor(string)");

            tse = new TaskSchedulerException(message, ioe);
            Assert.True(tse.InnerException == ioe, "RunTaskSchedulerExceptionTests:  Expected InnerException == ioe passed to ctor(string, ex)");
            Assert.True(tse.Message.Equals(message), "RunTaskSchedulerExceptionTests:  Expected Message = message passed to ctor(string, ex)");
        }
Ejemplo n.º 7
0
 private void RecordException(TaskSchedulerException taskSchedulerException)
 {
     AddException(taskSchedulerException);
     Finish(false);
     if ((_internalOptions & InternalTaskOptions.ContinuationTask) != 0)
     {
         return;
     }
     if (_exceptionsHolder != null)
     {
         Contract.Assert(_exceptionsHolder.ContainsFaultList, "Expected _exceptionsHolder to have faults recorded.");
         _exceptionsHolder.MarkAsHandled(false);
     }
     else
     {
         Contract.Assert(false, "Expected _exceptionsHolder to exist.");
     }
 }
Ejemplo n.º 8
0
 private bool PrivateStart(TaskScheduler scheduler, bool inline, bool throwSchedulerExceptions)
 {
     Scheduler = scheduler;
     var result = Interlocked.CompareExchange(ref _status, (int)TaskStatus.WaitingForActivation, (int)TaskStatus.Created);
     if (result != (int)TaskStatus.Created && result != (int)TaskStatus.WaitingForActivation)
     {
         return false;
     }
     var didInline = false;
     try
     {
         if (inline)
         {
             didInline = scheduler.TryExecuteTaskInline(this, IsScheduled);
         }
         if (!didInline)
         {
             scheduler.QueueTask(this);
             Interlocked.CompareExchange(ref _status, (int)TaskStatus.WaitingToRun, (int)TaskStatus.WaitingForActivation);
         }
         else
         {
             PrivateWait(CancellationToken, false);
         }
     }
     catch (ThreadAbortException exception)
     {
         if (!didInline)
         {
             AddException(exception);
             FinishThreadAbortedTask(true, false);
         }
     }
     catch (Exception exception)
     {
         var taskSchedulerException = new TaskSchedulerException(exception);
         RecordException(taskSchedulerException);
         if (throwSchedulerExceptions)
         {
             throw taskSchedulerException;
         }
     }
     return true;
 }
Ejemplo n.º 9
0
        internal bool InternalCancel(bool cancelNonExecutingOnly)
        {
            Contract.Requires((_internalOptions & InternalTaskOptions.PromiseTask) == 0, "Task.InternalCancel() did not expect promise-style task");

            var popSucceeded = false;
            var cancelSucceeded = false;
            TaskSchedulerException taskSchedulerException = null;

            RecordInternalCancellationRequest();

            var status = Thread.VolatileRead(ref _status);
            if (status <= (int)TaskStatus.WaitingToRun)
            {
                // Note: status may advance to TaskStatus.Running or even TaskStatus.RanToCompletion during the execution of this method
                var scheduler = Scheduler;
                var requiresAtomicStartTransition = scheduler.RequiresAtomicStartTransition;
                try
                {
                    popSucceeded = scheduler.TryDequeue(this);
                }
                catch (Exception exception)
                {
                    if (exception is InternalSpecialCancelException)
                    {
                        // Special path for ThreadPool
                        requiresAtomicStartTransition = true;
                    }
                    else if (exception is ThreadAbortException)
                    {
                        // Ignore the exception
                    }
                    else
                    {
                        taskSchedulerException = new TaskSchedulerException(exception);
                    }
                }
                if (!popSucceeded && requiresAtomicStartTransition)
                {
                    status = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.Created);
                    cancelSucceeded = status == (int)TaskStatus.Created;
                    status = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.WaitingForActivation);
                    cancelSucceeded = cancelSucceeded || status == (int)TaskStatus.WaitingForActivation;
                    status = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.WaitingToRun);
                    cancelSucceeded = cancelSucceeded || status == (int)TaskStatus.WaitingToRun;
                }
            }
            if (Thread.VolatileRead(ref _status) >= (int)TaskStatus.Running && !cancelNonExecutingOnly)
            {
                // We are going to pretend that the cancel call came after the task finished running, but we may still set to cancel on TaskStatus.WaitingForChildrenToComplete
                status = Interlocked.CompareExchange(ref _status, (int)TaskStatus.Canceled, (int)TaskStatus.WaitingForChildrenToComplete);
                cancelSucceeded = cancelSucceeded || status == (int)TaskStatus.WaitingForChildrenToComplete;
            }
            if (cancelSucceeded)
            {
                SetCompleted();
                FinishStageThree();
            }
            if (taskSchedulerException != null)
            {
                throw taskSchedulerException;
            }
            return cancelSucceeded;
        }