CancellationToken.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Threading / CancellationToken.cs / 1305376 / CancellationToken.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
//
// [....] 
//////////////////////////////////////////////////////////////////////////////// 

#pragma warning disable 0420 // turn off 'a reference to a volatile field will not be treated as volatile' during CAS. 

using System;
using System.Diagnostics;
using System.Runtime.InteropServices; 
using System.Security.Permissions;
using System.Diagnostics.Contracts; 
 
namespace System.Threading
{ 
    /// 
    /// Propogates notification that operations should be canceled.
    /// 
    ///  
    /// 
    /// A  may be created directly in an unchangeable canceled or non-canceled state 
    /// using the CancellationToken's constructors. However, to have a CancellationToken that can change 
    /// from a non-canceled to a canceled state,
    /// CancellationTokenSource must be used. 
    /// CancellationTokenSource exposes the associated CancellationToken that may be canceled by the source through its
    /// Token property.
    /// 
    ///  
    /// Once canceled, a token may not transition to a non-canceled state, and a token whose
    ///  is false will never change to one that can be canceled. 
    ///  
    /// 
    /// All members of this struct are thread-safe and may be used concurrently from multiple threads. 
    /// 
    /// 
    [ComVisible(false)]
    [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] 
    [DebuggerDisplay("IsCancellationRequested = {IsCancellationRequested}")]
    public struct CancellationToken 
    { 
        // The backing TokenSource.
        // if null, it implicitly represents the same thing as new CancellationToken(false). 
        // When required, it will be instantiated to reflect this.
        private CancellationTokenSource m_source;
        //!! warning. If more fields are added, the assumptions in CreateLinkedToken may no longer be valid
 
        /* Properties */
 
        ///  
        /// Returns an empty CancellationToken value.
        ///  
        /// 
        /// The  value returned by this property will be non-cancelable by default.
        /// 
        public static CancellationToken None 
        {
            get 
            { 
                return new CancellationToken();
            } 
        }

        /// 
        /// Gets whether cancellation has been requested for this token. 
        /// 
        /// Whether cancellation has been requested for this token. 
        ///  
        /// 
        /// This property indicates whether cancellation has been requested for this token, 
        /// either through the token initially being construted in a canceled state, or through
        /// calling Cancel
        /// on the token's associated .
        ///  
        /// 
        /// If this property is true, it only guarantees that cancellation has been requested. 
        /// It does not guarantee that every registered handler 
        /// has finished executing, nor that cancellation requests have finished propagating
        /// to all registered handlers.  Additional synchronization may be required, 
        /// particularly in situations where related objects are being canceled concurrently.
        /// 
        /// 
        public bool IsCancellationRequested { 
            get
            { 
                return m_source != null && m_source.IsCancellationRequested; 
            }
        } 

        /// 
        /// Gets whether this token is capable of being in the canceled state.
        ///  
        /// 
        /// If CanBeCanceled returns false, it is guaranteed that the token will never transition 
        /// into a canceled state, meaning that  will never 
        /// return true.
        ///  
        public bool CanBeCanceled
        {
            get
            { 
                return m_source != null && m_source.CanBeCanceled;
            } 
        } 

        ///  
        /// Gets a  that is signaled when the token is canceled.
        /// 
        /// Accessing this property causes a WaitHandle
        /// to be instantiated.  It is preferable to only use this property when necessary, and to then 
        /// dispose the associated  instance at the earliest opportunity (disposing
        /// the source will dispose of this allocated handle).  The handle should not be closed or disposed directly. 
        ///  
        /// The associated CancellationTokenSource has been disposed. 
        public WaitHandle WaitHandle
        {
            get
            { 
                if (m_source == null)
                { 
                    InitializeDefaultSource(); 
                }
 
                return m_source.WaitHandle;
            }
        }
 
        // public CancellationToken()
        // this constructor is implicit for structs 
        //   -> this should behaves exactly as for new CancellationToken(false) 

        ///  
        /// Internal constructor only a CancellationTokenSource should create a CancellationToken
        /// 
        internal CancellationToken(CancellationTokenSource source)
        { 
            m_source = source;
        } 
 
        /// 
        /// Initializes the CancellationToken. 
        /// 
        /// 
        /// The canceled state for the token.
        ///  
        /// 
        /// Tokens created with this constructor will remain in the canceled state specified 
        /// by the  parameter.  If  is false, 
        /// both  and  will be false.
        /// If  is true, 
        /// both  and  will be true.
        /// 
        public CancellationToken(bool canceled) :
            this() 
        {
            if(canceled) 
                m_source = CancellationTokenSource.InternalGetStaticSource(canceled); 
        }
 
        /* Methods */


        private static Action s_ActionToActionObjShunt = new Action(ActionToActionObjShunt); 
        private static void ActionToActionObjShunt(object obj)
        { 
            Action action = obj as Action; 
            Contract.Assert(action != null, "Expected an Action here");
            action(); 
        }

        /// 
        /// Registers a delegate that will be called when this CancellationToken is canceled. 
        /// 
        ///  
        ///  
        /// If this token is already in the canceled state, the
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be 
        /// propogated out of this method call.
        /// 
        /// 
        /// The current ExecutionContext, if one exists, will be captured 
        /// along with the delegate and will be used when executing it.
        ///  
        ///  
        /// The delegate to be executed when the CancellationToken is canceled.
        /// The  instance that can 
        /// be used to deregister the callback.
        ///  is null.
        /// The associated CancellationTokenSource has been disposed. 
        public CancellationTokenRegistration Register(Action callback)
        { 
            if (callback == null) 
                throw new ArgumentNullException("callback");
 
            return Register(
                s_ActionToActionObjShunt,
                callback,
                false, // useSync=false 
                true   // useExecutionContext=true
             ); 
        } 

        ///  
        /// Registers a delegate that will be called when this
        /// CancellationToken is canceled.
        /// 
        ///  
        /// 
        /// If this token is already in the canceled state, the 
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be 
        /// propogated out of this method call.
        ///  
        /// 
        /// The current ExecutionContext, if one exists, will be captured
        /// along with the delegate and will be used when executing it.
        ///  
        /// 
        /// The delegate to be executed when the CancellationToken is canceled. 
        /// A Boolean value that indicates whether to capture 
        /// the current SynchronizationContext and use it
        /// when invoking the . 
        /// The  instance that can
        /// be used to deregister the callback.
        ///  is null.
        /// The associated CancellationTokenSource has been disposed.
        public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext) 
        { 
            if (callback == null)
                throw new ArgumentNullException("callback"); 

            return Register(
                s_ActionToActionObjShunt,
                callback, 
                useSynchronizationContext,
                true   // useExecutionContext=true 
             ); 
        }
 
        /// 
        /// Registers a delegate that will be called when this
        /// CancellationToken is canceled.
        ///  
        /// 
        ///  
        /// If this token is already in the canceled state, the 
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be
        /// propogated out of this method call. 
        /// 
        /// 
        /// The current ExecutionContext, if one exists, will be captured
        /// along with the delegate and will be used when executing it. 
        /// 
        ///  
        /// The delegate to be executed when the CancellationToken is canceled. 
        /// The state to pass to the  when the delegate is invoked.  This may be null.
        /// The  instance that can 
        /// be used to deregister the callback.
        ///  is null.
        /// The associated CancellationTokenSource has been disposed. 
        public CancellationTokenRegistration Register(Action callback, Object state)
        { 
            if (callback == null) 
                throw new ArgumentNullException("callback");
 
            return Register(
                callback,
                state,
                false, // useSync=false 
                true   // useExecutionContext=true
             ); 
        } 

        ///  
        /// Registers a delegate that will be called when this
        /// CancellationToken is canceled.
        /// 
        ///  
        /// 
        /// If this token is already in the canceled state, the 
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be 
        /// propogated out of this method call.
        ///  
        /// 
        /// The current ExecutionContext, if one exists,
        /// will be captured along with the delegate and will be used when executing it.
        ///  
        /// 
        /// The delegate to be executed when the CancellationToken is canceled. 
        /// The state to pass to the  when the delegate is invoked.  This may be null. 
        /// A Boolean value that indicates whether to capture
        /// the current SynchronizationContext and use it 
        /// when invoking the .
        /// The  instance that can
        /// be used to deregister the callback.
        ///  is null. 
        /// The associated CancellationTokenSource has been disposed. 
        public CancellationTokenRegistration Register(Action callback, Object state, bool useSynchronizationContext) 
        {
            return Register( 
                callback,
                state,
                useSynchronizationContext,
                true   // useExecutionContext=true 
             );
        } 
 
        // helper for internal registration needs that don't require an EC capture (e.g. creating linked token sources, or registering unstarted TPL tasks)
        // has a handy signature, and skips capturing execution context. 
        internal CancellationTokenRegistration InternalRegisterWithoutEC(Action callback, Object state)
        {
            return Register(
                callback, 
                state,
                false, // useSyncContext=false 
                false  // useExecutionContext=false 
             );
        } 

        // the real work..
        private CancellationTokenRegistration Register(Action callback, Object state, bool useSynchronizationContext, bool useExecutionContext)
        { 
            if (callback == null)
                throw new ArgumentNullException("callback"); 
 
            if(CanBeCanceled == false)
            { 
                return new CancellationTokenRegistration(); // nothing to do for tokens than can never reach the canceled state. Give them a dummy registration.
            }

            // Capture [....]/execution contexts if required. 
            // Note: Only capture [....]/execution contexts if IsCancellationRequested = false
            // as we know that if it is true that the callback will just be called synchronously. 
 
            SynchronizationContext capturedSyncContext = null;
            if (!IsCancellationRequested && useSynchronizationContext) 
                capturedSyncContext = SynchronizationContext.Current;

            ExecutionContext capturedExecutionContext = null;
            if (!IsCancellationRequested && useExecutionContext) 
                capturedExecutionContext = ExecutionContext.Capture();
 
            // Register the callback with the source. 
            return m_source.InternalRegister(callback, state, capturedSyncContext, capturedExecutionContext);
        } 

        /// 
        /// Determines whether the current CancellationToken instance is equal to the
        /// specified token. 
        /// 
        /// The other CancellationToken to which to compare this 
        /// instance. 
        /// True if the instances are equal; otherwise, false. Two tokens are equal if they are associated
        /// with the same CancellationTokenSource or if they were both constructed 
        /// from public CancellationToken constructors and their  values are equal.
        public bool Equals(CancellationToken other)
        {
            //if both sources are null, then both tokens represent the Empty token. 
            if (m_source == null && other.m_source == null)
            { 
                return true; 
            }
 
            // one is null but other has inflated the default source
            // these are only equal if the inflated one is the staticSource(false)
            if (m_source == null)
            { 
                return other.m_source == CancellationTokenSource.InternalGetStaticSource(false);
            } 
 
            if (other.m_source == null)
            { 
                return m_source == CancellationTokenSource.InternalGetStaticSource(false);
            }

            // general case, we check if the sources are identical 

            return m_source == other.m_source; 
        } 

        ///  
        /// Determines whether the current CancellationToken instance is equal to the
        /// specified .
        /// 
        /// The other object to which to compare this instance. 
        /// True if  is a CancellationToken
        /// and if the two instances are equal; otherwise, false. Two tokens are equal if they are associated 
        /// with the same CancellationTokenSource or if they were both constructed 
        /// from public CancellationToken constructors and their  values are equal.
        /// An associated CancellationTokenSource has been disposed.
        public override bool Equals(Object other)
        {
            if (other is CancellationToken) 
            {
                return Equals((CancellationToken) other); 
            } 

            return false; 
        }

        /// 
        /// Serves as a hash function for a CancellationToken. 
        /// 
        /// A hash code for the current CancellationToken instance. 
        public override Int32 GetHashCode() 
        {
            if (m_source == null) 
            {
                // link to the common source so that we have a source to interrogate.
                return CancellationTokenSource.InternalGetStaticSource(false).GetHashCode();
            } 

            return m_source.GetHashCode(); 
        } 

        ///  
        /// Determines whether two CancellationToken instances are equal.
        /// 
        /// The first instance.
        /// The second instance. 
        /// True if the instances are equal; otherwise, false.
        /// An associated CancellationTokenSource has been disposed. 
        public static bool operator ==(CancellationToken left, CancellationToken right)
        { 
            return left.Equals(right);
        }

        ///  
        /// Determines whether two CancellationToken instances are not equal.
        ///  
        /// The first instance. 
        /// The second instance.
        /// True if the instances are not equal; otherwise, false. 
        /// An associated CancellationTokenSource has been disposed.
        public static bool operator !=(CancellationToken left, CancellationToken right)
        { 
            return !left.Equals(right);
        } 
 
        /// 
        /// Throws a OperationCanceledException if 
        /// this token has had cancellation requested.
        /// 
        /// 
        /// This method provides functionality equivalent to: 
        /// 
        /// if (token.IsCancellationRequested) 
        ///    throw new OperationCanceledException(token); 
        /// 
        ///  
        /// The token has had cancellation requested.
        /// The associated CancellationTokenSource has been disposed.
        public void ThrowIfCancellationRequested() 
        {
            if (IsCancellationRequested) 
                throw new OperationCanceledException(Environment.GetResourceString("OperationCanceled"), this); 
        }
 
        // Throw an ODE if this CancellationToken's source is disposed.
        internal void ThrowIfSourceDisposed()
        {
            if ((m_source != null) && m_source.IsDisposed) 
            {
                throw new ObjectDisposedException(null, Environment.GetResourceString("CancellationToken_SourceDisposed")); 
            } 
        }
 

        // -----------------------------------
        // Private helpers
 
        private void InitializeDefaultSource()
        { 
            // Lazy is slower, and although multiple threads may ---- and set m_source repeatedly, the ---- is benign. 
            // Alternative: LazyInititalizer.EnsureInitialized(ref m_source, ()=>CancellationTokenSource.InternalGetStaticSource(false));
 
            m_source = CancellationTokenSource.InternalGetStaticSource(false);
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
//
// [....] 
//////////////////////////////////////////////////////////////////////////////// 

#pragma warning disable 0420 // turn off 'a reference to a volatile field will not be treated as volatile' during CAS. 

using System;
using System.Diagnostics;
using System.Runtime.InteropServices; 
using System.Security.Permissions;
using System.Diagnostics.Contracts; 
 
namespace System.Threading
{ 
    /// 
    /// Propogates notification that operations should be canceled.
    /// 
    ///  
    /// 
    /// A  may be created directly in an unchangeable canceled or non-canceled state 
    /// using the CancellationToken's constructors. However, to have a CancellationToken that can change 
    /// from a non-canceled to a canceled state,
    /// CancellationTokenSource must be used. 
    /// CancellationTokenSource exposes the associated CancellationToken that may be canceled by the source through its
    /// Token property.
    /// 
    ///  
    /// Once canceled, a token may not transition to a non-canceled state, and a token whose
    ///  is false will never change to one that can be canceled. 
    ///  
    /// 
    /// All members of this struct are thread-safe and may be used concurrently from multiple threads. 
    /// 
    /// 
    [ComVisible(false)]
    [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] 
    [DebuggerDisplay("IsCancellationRequested = {IsCancellationRequested}")]
    public struct CancellationToken 
    { 
        // The backing TokenSource.
        // if null, it implicitly represents the same thing as new CancellationToken(false). 
        // When required, it will be instantiated to reflect this.
        private CancellationTokenSource m_source;
        //!! warning. If more fields are added, the assumptions in CreateLinkedToken may no longer be valid
 
        /* Properties */
 
        ///  
        /// Returns an empty CancellationToken value.
        ///  
        /// 
        /// The  value returned by this property will be non-cancelable by default.
        /// 
        public static CancellationToken None 
        {
            get 
            { 
                return new CancellationToken();
            } 
        }

        /// 
        /// Gets whether cancellation has been requested for this token. 
        /// 
        /// Whether cancellation has been requested for this token. 
        ///  
        /// 
        /// This property indicates whether cancellation has been requested for this token, 
        /// either through the token initially being construted in a canceled state, or through
        /// calling Cancel
        /// on the token's associated .
        ///  
        /// 
        /// If this property is true, it only guarantees that cancellation has been requested. 
        /// It does not guarantee that every registered handler 
        /// has finished executing, nor that cancellation requests have finished propagating
        /// to all registered handlers.  Additional synchronization may be required, 
        /// particularly in situations where related objects are being canceled concurrently.
        /// 
        /// 
        public bool IsCancellationRequested { 
            get
            { 
                return m_source != null && m_source.IsCancellationRequested; 
            }
        } 

        /// 
        /// Gets whether this token is capable of being in the canceled state.
        ///  
        /// 
        /// If CanBeCanceled returns false, it is guaranteed that the token will never transition 
        /// into a canceled state, meaning that  will never 
        /// return true.
        ///  
        public bool CanBeCanceled
        {
            get
            { 
                return m_source != null && m_source.CanBeCanceled;
            } 
        } 

        ///  
        /// Gets a  that is signaled when the token is canceled.
        /// 
        /// Accessing this property causes a WaitHandle
        /// to be instantiated.  It is preferable to only use this property when necessary, and to then 
        /// dispose the associated  instance at the earliest opportunity (disposing
        /// the source will dispose of this allocated handle).  The handle should not be closed or disposed directly. 
        ///  
        /// The associated CancellationTokenSource has been disposed. 
        public WaitHandle WaitHandle
        {
            get
            { 
                if (m_source == null)
                { 
                    InitializeDefaultSource(); 
                }
 
                return m_source.WaitHandle;
            }
        }
 
        // public CancellationToken()
        // this constructor is implicit for structs 
        //   -> this should behaves exactly as for new CancellationToken(false) 

        ///  
        /// Internal constructor only a CancellationTokenSource should create a CancellationToken
        /// 
        internal CancellationToken(CancellationTokenSource source)
        { 
            m_source = source;
        } 
 
        /// 
        /// Initializes the CancellationToken. 
        /// 
        /// 
        /// The canceled state for the token.
        ///  
        /// 
        /// Tokens created with this constructor will remain in the canceled state specified 
        /// by the  parameter.  If  is false, 
        /// both  and  will be false.
        /// If  is true, 
        /// both  and  will be true.
        /// 
        public CancellationToken(bool canceled) :
            this() 
        {
            if(canceled) 
                m_source = CancellationTokenSource.InternalGetStaticSource(canceled); 
        }
 
        /* Methods */


        private static Action s_ActionToActionObjShunt = new Action(ActionToActionObjShunt); 
        private static void ActionToActionObjShunt(object obj)
        { 
            Action action = obj as Action; 
            Contract.Assert(action != null, "Expected an Action here");
            action(); 
        }

        /// 
        /// Registers a delegate that will be called when this CancellationToken is canceled. 
        /// 
        ///  
        ///  
        /// If this token is already in the canceled state, the
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be 
        /// propogated out of this method call.
        /// 
        /// 
        /// The current ExecutionContext, if one exists, will be captured 
        /// along with the delegate and will be used when executing it.
        ///  
        ///  
        /// The delegate to be executed when the CancellationToken is canceled.
        /// The  instance that can 
        /// be used to deregister the callback.
        ///  is null.
        /// The associated CancellationTokenSource has been disposed. 
        public CancellationTokenRegistration Register(Action callback)
        { 
            if (callback == null) 
                throw new ArgumentNullException("callback");
 
            return Register(
                s_ActionToActionObjShunt,
                callback,
                false, // useSync=false 
                true   // useExecutionContext=true
             ); 
        } 

        ///  
        /// Registers a delegate that will be called when this
        /// CancellationToken is canceled.
        /// 
        ///  
        /// 
        /// If this token is already in the canceled state, the 
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be 
        /// propogated out of this method call.
        ///  
        /// 
        /// The current ExecutionContext, if one exists, will be captured
        /// along with the delegate and will be used when executing it.
        ///  
        /// 
        /// The delegate to be executed when the CancellationToken is canceled. 
        /// A Boolean value that indicates whether to capture 
        /// the current SynchronizationContext and use it
        /// when invoking the . 
        /// The  instance that can
        /// be used to deregister the callback.
        ///  is null.
        /// The associated CancellationTokenSource has been disposed.
        public CancellationTokenRegistration Register(Action callback, bool useSynchronizationContext) 
        { 
            if (callback == null)
                throw new ArgumentNullException("callback"); 

            return Register(
                s_ActionToActionObjShunt,
                callback, 
                useSynchronizationContext,
                true   // useExecutionContext=true 
             ); 
        }
 
        /// 
        /// Registers a delegate that will be called when this
        /// CancellationToken is canceled.
        ///  
        /// 
        ///  
        /// If this token is already in the canceled state, the 
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be
        /// propogated out of this method call. 
        /// 
        /// 
        /// The current ExecutionContext, if one exists, will be captured
        /// along with the delegate and will be used when executing it. 
        /// 
        ///  
        /// The delegate to be executed when the CancellationToken is canceled. 
        /// The state to pass to the  when the delegate is invoked.  This may be null.
        /// The  instance that can 
        /// be used to deregister the callback.
        ///  is null.
        /// The associated CancellationTokenSource has been disposed. 
        public CancellationTokenRegistration Register(Action callback, Object state)
        { 
            if (callback == null) 
                throw new ArgumentNullException("callback");
 
            return Register(
                callback,
                state,
                false, // useSync=false 
                true   // useExecutionContext=true
             ); 
        } 

        ///  
        /// Registers a delegate that will be called when this
        /// CancellationToken is canceled.
        /// 
        ///  
        /// 
        /// If this token is already in the canceled state, the 
        /// delegate will be run immediately and synchronously. Any exception the delegate generates will be 
        /// propogated out of this method call.
        ///  
        /// 
        /// The current ExecutionContext, if one exists,
        /// will be captured along with the delegate and will be used when executing it.
        ///  
        /// 
        /// The delegate to be executed when the CancellationToken is canceled. 
        /// The state to pass to the  when the delegate is invoked.  This may be null. 
        /// A Boolean value that indicates whether to capture
        /// the current SynchronizationContext and use it 
        /// when invoking the .
        /// The  instance that can
        /// be used to deregister the callback.
        ///  is null. 
        /// The associated CancellationTokenSource has been disposed. 
        public CancellationTokenRegistration Register(Action callback, Object state, bool useSynchronizationContext) 
        {
            return Register( 
                callback,
                state,
                useSynchronizationContext,
                true   // useExecutionContext=true 
             );
        } 
 
        // helper for internal registration needs that don't require an EC capture (e.g. creating linked token sources, or registering unstarted TPL tasks)
        // has a handy signature, and skips capturing execution context. 
        internal CancellationTokenRegistration InternalRegisterWithoutEC(Action callback, Object state)
        {
            return Register(
                callback, 
                state,
                false, // useSyncContext=false 
                false  // useExecutionContext=false 
             );
        } 

        // the real work..
        private CancellationTokenRegistration Register(Action callback, Object state, bool useSynchronizationContext, bool useExecutionContext)
        { 
            if (callback == null)
                throw new ArgumentNullException("callback"); 
 
            if(CanBeCanceled == false)
            { 
                return new CancellationTokenRegistration(); // nothing to do for tokens than can never reach the canceled state. Give them a dummy registration.
            }

            // Capture [....]/execution contexts if required. 
            // Note: Only capture [....]/execution contexts if IsCancellationRequested = false
            // as we know that if it is true that the callback will just be called synchronously. 
 
            SynchronizationContext capturedSyncContext = null;
            if (!IsCancellationRequested && useSynchronizationContext) 
                capturedSyncContext = SynchronizationContext.Current;

            ExecutionContext capturedExecutionContext = null;
            if (!IsCancellationRequested && useExecutionContext) 
                capturedExecutionContext = ExecutionContext.Capture();
 
            // Register the callback with the source. 
            return m_source.InternalRegister(callback, state, capturedSyncContext, capturedExecutionContext);
        } 

        /// 
        /// Determines whether the current CancellationToken instance is equal to the
        /// specified token. 
        /// 
        /// The other CancellationToken to which to compare this 
        /// instance. 
        /// True if the instances are equal; otherwise, false. Two tokens are equal if they are associated
        /// with the same CancellationTokenSource or if they were both constructed 
        /// from public CancellationToken constructors and their  values are equal.
        public bool Equals(CancellationToken other)
        {
            //if both sources are null, then both tokens represent the Empty token. 
            if (m_source == null && other.m_source == null)
            { 
                return true; 
            }
 
            // one is null but other has inflated the default source
            // these are only equal if the inflated one is the staticSource(false)
            if (m_source == null)
            { 
                return other.m_source == CancellationTokenSource.InternalGetStaticSource(false);
            } 
 
            if (other.m_source == null)
            { 
                return m_source == CancellationTokenSource.InternalGetStaticSource(false);
            }

            // general case, we check if the sources are identical 

            return m_source == other.m_source; 
        } 

        ///  
        /// Determines whether the current CancellationToken instance is equal to the
        /// specified .
        /// 
        /// The other object to which to compare this instance. 
        /// True if  is a CancellationToken
        /// and if the two instances are equal; otherwise, false. Two tokens are equal if they are associated 
        /// with the same CancellationTokenSource or if they were both constructed 
        /// from public CancellationToken constructors and their  values are equal.
        /// An associated CancellationTokenSource has been disposed.
        public override bool Equals(Object other)
        {
            if (other is CancellationToken) 
            {
                return Equals((CancellationToken) other); 
            } 

            return false; 
        }

        /// 
        /// Serves as a hash function for a CancellationToken. 
        /// 
        /// A hash code for the current CancellationToken instance. 
        public override Int32 GetHashCode() 
        {
            if (m_source == null) 
            {
                // link to the common source so that we have a source to interrogate.
                return CancellationTokenSource.InternalGetStaticSource(false).GetHashCode();
            } 

            return m_source.GetHashCode(); 
        } 

        ///  
        /// Determines whether two CancellationToken instances are equal.
        /// 
        /// The first instance.
        /// The second instance. 
        /// True if the instances are equal; otherwise, false.
        /// An associated CancellationTokenSource has been disposed. 
        public static bool operator ==(CancellationToken left, CancellationToken right)
        { 
            return left.Equals(right);
        }

        ///  
        /// Determines whether two CancellationToken instances are not equal.
        ///  
        /// The first instance. 
        /// The second instance.
        /// True if the instances are not equal; otherwise, false. 
        /// An associated CancellationTokenSource has been disposed.
        public static bool operator !=(CancellationToken left, CancellationToken right)
        { 
            return !left.Equals(right);
        } 
 
        /// 
        /// Throws a OperationCanceledException if 
        /// this token has had cancellation requested.
        /// 
        /// 
        /// This method provides functionality equivalent to: 
        /// 
        /// if (token.IsCancellationRequested) 
        ///    throw new OperationCanceledException(token); 
        /// 
        ///  
        /// The token has had cancellation requested.
        /// The associated CancellationTokenSource has been disposed.
        public void ThrowIfCancellationRequested() 
        {
            if (IsCancellationRequested) 
                throw new OperationCanceledException(Environment.GetResourceString("OperationCanceled"), this); 
        }
 
        // Throw an ODE if this CancellationToken's source is disposed.
        internal void ThrowIfSourceDisposed()
        {
            if ((m_source != null) && m_source.IsDisposed) 
            {
                throw new ObjectDisposedException(null, Environment.GetResourceString("CancellationToken_SourceDisposed")); 
            } 
        }
 

        // -----------------------------------
        // Private helpers
 
        private void InitializeDefaultSource()
        { 
            // Lazy is slower, and although multiple threads may ---- and set m_source repeatedly, the ---- is benign. 
            // Alternative: LazyInititalizer.EnsureInitialized(ref m_source, ()=>CancellationTokenSource.InternalGetStaticSource(false));
 
            m_source = CancellationTokenSource.InternalGetStaticSource(false);
        }
    }
} 

// 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