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