TaskResultSetter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / Tasks / TaskResultSetter.cs / 1305376 / TaskResultSetter.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
// 
// TaskCompletionSource.cs 
//
// [....] 
//
// TaskCompletionSource is the producer end of an unbound future.  Its
// Task member may be distributed as the consumer end of the future.
// 
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 
using System; 
using System.Security.Permissions;
using System.Threading; 
using System.Diagnostics.Contracts;
using System.Collections.Generic;

// Disable the "reference to volatile field not treated as volatile" error. 
#pragma warning disable 0420
 
namespace System.Threading.Tasks 
{
    ///  
    /// Represents the producer side of a  unbound to a
    /// delegate, providing access to the consumer side through the  property.
    /// 
    ///  
    /// 
    /// It is often the case that a  is desired to 
    /// represent another asynchronous operation. 
    /// TaskCompletionSource is provided for this purpose. It enables
    /// the creation of a task that can be handed out to consumers, and those consumers can use the members 
    /// of the task as they would any other. However, unlike most tasks, the state of a task created by a
    /// TaskCompletionSource is controlled explicitly by the methods on TaskCompletionSource. This enables the
    /// completion of the external asynchronous operation to be propagated to the underlying Task. The
    /// separation also ensures that consumers are not able to transition the state without access to the 
    /// corresponding TaskCompletionSource.
    ///  
    ///  
    /// All members of  are thread-safe
    /// and may be used from multiple threads concurrently. 
    /// 
    /// 
    /// The type of the result value assocatied with this . 
    [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
    public class TaskCompletionSource 
    { 
        private Task m_task;
 
        /// 
        /// Creates a .
        /// 
        public TaskCompletionSource() 
            : this(null, TaskCreationOptions.None)
        { 
        } 

        ///  
        /// Creates a 
        /// with the specified options.
        /// 
        ///  
        /// The  created
        /// by this instance and accessible through its  property 
        /// will be instantiated using the specified . 
        /// 
        /// The options to use when creating the underlying 
        /// .
        /// 
        /// The  represent options invalid for use
        /// with a . 
        /// 
        public TaskCompletionSource(TaskCreationOptions creationOptions) 
            : this(null, creationOptions) 
        {
        } 

        /// 
        /// Creates a 
        /// with the specified state. 
        /// 
        /// The state to use as the underlying 
        /// 's AsyncState. 
        public TaskCompletionSource(object state)
            : this(state, TaskCreationOptions.None) 
        {
        }

        ///  
        /// Creates a  with
        /// the specified state and options. 
        ///  
        /// The options to use when creating the underlying
        /// . 
        /// The state to use as the underlying
        /// 's AsyncState.
        /// 
        /// The  represent options invalid for use 
        /// with a .
        ///  
        public TaskCompletionSource(object state, TaskCreationOptions creationOptions) 
        {
            m_task = new Task(state, CancellationToken.None, creationOptions, InternalTaskOptions.PromiseTask); 
        }


        ///  
        /// Gets the  created
        /// by this . 
        ///  
        /// 
        /// This property enables a consumer access to the  that is controlled by this instance.
        /// The , ,
        /// , and 
        /// methods (and their "Try" variants) on this instance all result in the relevant state 
        /// transitions on this underlying Task.
        ///  
        public Task Task 
        {
            get { return m_task; } 
        }

        /// 
        /// Attempts to transition the underlying 
        ///  into the
        /// Faulted 
        /// state. 
        /// 
        /// The exception to bind to this .
        /// True if the operation was successful; otherwise, false.
        /// This operation will return false if the
        ///  is already in one 
        /// of the three final states:
        /// RanToCompletion, 
        /// Faulted, or 
        /// Canceled.
        ///  
        /// The  argument is null.
        /// The  was disposed.
        public bool TrySetException(Exception exception)
        { 
            if (exception == null) throw new ArgumentNullException("exception");
 
            bool rval = m_task.TrySetException(exception); 
            if (!rval && !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 rval; 
        }
 
        /// 
        /// Attempts to transition the underlying
        ///  into the
        /// Faulted 
        /// state.
        ///  
        /// The collection of exceptions to bind to this .
        /// True if the operation was successful; otherwise, false. 
        /// This operation will return false if the
        ///  is already in one
        /// of the three final states:
        /// RanToCompletion, 
        /// Faulted, or
        /// Canceled. 
        ///  
        /// The  argument is null.
        /// There are one or more null elements in . 
        /// The  collection is empty.
        /// The  was disposed.
        public bool TrySetException(IEnumerable exceptions)
        { 
            if (exceptions == null) throw new ArgumentNullException("exceptions");
 
            List defensiveCopy = new List(); 
            foreach (Exception e in exceptions)
            { 
                if (e == null)
                    throw new ArgumentException(Environment.GetResourceString("TaskCompletionSourceT_TrySetException_NullException"), "exceptions");
                defensiveCopy.Add(e);
            } 

            if (defensiveCopy.Count == 0) 
                throw new ArgumentException(Environment.GetResourceString("TaskCompletionSourceT_TrySetException_NoExceptions"), "exceptions"); 

            bool rval = m_task.TrySetException(defensiveCopy); 
            if (!rval && !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 rval; 
        }

        /// 
        /// Transitions the underlying 
        ///  into the
        /// Faulted 
        /// state. 
        /// 
        /// The exception to bind to this .
        /// The  argument is null.
        /// 
        /// The underlying  is already in one 
        /// of the three final states:
        /// RanToCompletion, 
        /// Faulted, or 
        /// Canceled.
        ///  
        /// The  was disposed.
        public void SetException(Exception exception)
        {
            if (exception == null) throw new ArgumentNullException("exception"); 

            if (!TrySetException(exception)) 
            { 
                throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted"));
            } 
        }

        /// 
        /// Transitions the underlying 
        ///  into the
        /// Faulted 
        /// state. 
        /// 
        /// The collection of exceptions to bind to this .
        /// The  argument is null.
        /// There are one or more null elements in .
        ///  
        /// The underlying  is already in one
        /// of the three final states: 
        /// RanToCompletion, 
        /// Faulted, or
        /// Canceled. 
        /// 
        /// The  was disposed.
        public void SetException(IEnumerable exceptions)
        { 
            if (!TrySetException(exceptions))
            { 
                throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted")); 
            }
        } 


        /// 
        /// Attempts to transition the underlying 
        ///  into the
        /// RanToCompletion 
        /// state. 
        /// 
        /// The result value to bind to this .
        /// True if the operation was successful; otherwise, false.
        /// This operation will return false if the
        ///  is already in one 
        /// of the three final states:
        /// RanToCompletion, 
        /// Faulted, or 
        /// Canceled.
        ///  
        /// The  was disposed.
        public bool TrySetResult(TResult result)
        {
            // Attempt to quickly recognize failure. 
            if (m_task.IsCompleted)
            { 
                return false; 
            }
 
            bool rval = m_task.TrySetResult(result);
            if(!rval && !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 rval;
        }

        ///  
        /// Transitions the underlying
        ///  into the 
        /// RanToCompletion 
        /// state.
        ///  
        /// The result value to bind to this .
        /// 
        /// The underlying  is already in one 
        /// of the three final states:
        /// RanToCompletion, 
        /// Faulted, or 
        /// Canceled.
        ///  
        /// The  was disposed.
        public void SetResult(TResult result)
        {
            m_task.Result = result; 
        }
 
        ///  
        /// Transitions the underlying
        ///  into the 
        /// Canceled
        /// state.
        /// 
        ///  
        /// The underlying  is already in one
        /// of the three final states: 
        /// RanToCompletion, 
        /// Faulted, or
        /// Canceled. 
        /// 
        /// The  was disposed.
        public void SetCanceled()
        { 
            if(!TrySetCanceled())
                throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted")); 
        } 

        ///  
        /// Attempts to transition the underlying
        ///  into the
        /// Canceled
        /// state. 
        /// 
        /// True if the operation was successful; otherwise, false. 
        /// This operation will return false if the 
        ///  is already in one
        /// of the three final states: 
        /// RanToCompletion,
        /// Faulted, or
        /// Canceled.
        ///  
        /// The  was disposed.
        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 
            // instead of Task, because I have a property named Task and that
            // was confusing the compiler. 
            if (m_task.AtomicStateUpdate(Task.TASK_STATE_COMPLETION_RESERVED,
                Task.TASK_STATE_COMPLETION_RESERVED | Task.TASK_STATE_CANCELED |
                Task.TASK_STATE_FAULTED | Task.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; 
        }

    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK