Exemplo n.º 1
0
        /// <summary>
        /// Attempts to transition the underlying
        /// <see cref="T:System.Threading.Tasks.Task{TResult}"/> into the
        /// <see cref="System.Threading.Tasks.TaskStatus.Canceled">Canceled</see>
        /// state.
        /// </summary>
        /// <returns>True if the operation was successful; otherwise, false.</returns>
        /// <remarks>This operation will return false if the
        /// <see cref="T:System.Threading.Tasks.Task{TResult}"/> is already in one
        /// of the three final states:
        /// <see cref="System.Threading.Tasks.TaskStatus.RanToCompletion">RanToCompletion</see>,
        /// <see cref="System.Threading.Tasks.TaskStatus.Faulted">Faulted</see>, or
        /// <see cref="System.Threading.Tasks.TaskStatus.Canceled">Canceled</see>.
        /// </remarks>
        /// <exception cref="T:System.ObjectDisposedException">The <see cref="Task"/> was disposed.</exception>
        public bool TrySetCanceled()
        {
            bool returnValue = false;

            // "Reserve" the completion for this task, while making sure that: (1) No prior reservation
            // has been made, (2) The result has not already been set, (3) An exception has not previously
            // been recorded, and (4) Cancellation has not been requested.
            //
            // If the reservation is successful, then record the cancellation and finish completion processing.
            //
            // Note: I had to access static Task variables through Task<object>
            // instead of Task, because I have a property named Task and that
            // was confusing the compiler.
            if (m_task.AtomicStateUpdate(Task <object> .TASK_STATE_COMPLETION_RESERVED,
                                         Task <object> .TASK_STATE_COMPLETION_RESERVED | Task <object> .TASK_STATE_CANCELED |
                                         Task <object> .TASK_STATE_FAULTED | Task <object> .TASK_STATE_RAN_TO_COMPLETION))
            {
                m_task.RecordInternalCancellationRequest(); // record the request
                m_task.CancellationCleanupLogic();          // perform cancellation cleanup actions
                returnValue = true;
            }
            else if (!m_task.IsCompleted)
            {
                // The only way that m_task is not completed is if it is in a COMPLETION_RESERVED state.
                // Just wait a bit until the completion is finalized.
                SpinWait sw = new SpinWait();
                while (!m_task.IsCompleted)
                {
                    sw.SpinOnce();
                }
            }


            return(returnValue);
        }