コード例 #1
0
        /// <summary>
        /// Registers a callback object. If cancellation has already occurred, the
        /// callback will have been run by the time this method returns.
        /// </summary>
        internal CancellationTokenRegistration InternalRegister(
            Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
        {
            ThrowIfDisposed();

            // the CancellationToken has already checked that the token is cancelable before calling this method.
            Contract.Assert(CanBeCanceled, "Cannot register for uncancelable token src");

            // if not canceled, register the event handlers
            // if canceled already, run the callback synchronously
            // Apart from the semantics of late-enlistment, this also ensures that during ExecuteCallbackHandlers() there
            // will be no mutation of the _registeredCallbacks list

            if (!IsCancellationRequested)
            {
                int myIndex = Thread.CurrentThread.ManagedThreadId % s_nLists;

                CancellationCallbackInfo callbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);

                //allocate the callback list array
                if (m_registeredCallbacksLists == null)
                {
                    SparselyPopulatedArray <CancellationCallbackInfo>[] list = new SparselyPopulatedArray <CancellationCallbackInfo> [s_nLists];
                    Interlocked.CompareExchange(ref m_registeredCallbacksLists, list, null);
                }

                //allocate the actual lists on-demand to save mem in low-use situations, and to avoid false-sharing.
                if (m_registeredCallbacksLists[myIndex] == null)
                {
                    SparselyPopulatedArray <CancellationCallbackInfo> callBackArray = new SparselyPopulatedArray <CancellationCallbackInfo>(4);
                    Interlocked.CompareExchange(ref (m_registeredCallbacksLists[myIndex]), callBackArray, null);
                }

                // Now add the registration to the list.
                SparselyPopulatedArray <CancellationCallbackInfo>        callbacks = m_registeredCallbacksLists[myIndex];
                SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> addInfo   = callbacks.Add(callbackInfo);
                CancellationTokenRegistration registration = new CancellationTokenRegistration(this, callbackInfo, addInfo);

                if (!IsCancellationRequested)
                {
                    return(registration);
                }

                //If a cancellation has since come in, we will try to undo the registration and run the callback directly here.
                bool deregisterOccurred = registration.TryDeregister();

                if (!deregisterOccurred)
                {
                    // the callback execution process must have snagged the callback for execution, so
                    // 1. wait for the callback to complete, then
                    // 2. return a dummy registration.
                    WaitForCallbackToComplete(callbackInfo);
                    return(new CancellationTokenRegistration());
                }
            }

            // If cancellation already occurred, we run the callback on this thread and return an empty registration.
            callback(stateForCallback);
            return(new CancellationTokenRegistration());
        }
コード例 #2
0
 internal CancellationTokenRegistration InternalRegister(Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
 {
     this.ThrowIfDisposed();
     if (!this.IsCancellationRequested)
     {
         int index = Thread.CurrentThread.ManagedThreadId % s_nLists;
         CancellationCallbackInfo element = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);
         if (this.m_registeredCallbacksLists == null)
         {
             SparselyPopulatedArray <CancellationCallbackInfo>[] arrayArray = new SparselyPopulatedArray <CancellationCallbackInfo> [s_nLists];
             Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, arrayArray, null);
         }
         if (this.m_registeredCallbacksLists[index] == null)
         {
             SparselyPopulatedArray <CancellationCallbackInfo> array = new SparselyPopulatedArray <CancellationCallbackInfo>(4);
             Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo> >(ref this.m_registeredCallbacksLists[index], array, null);
         }
         SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> registrationInfo = this.m_registeredCallbacksLists[index].Add(element);
         CancellationTokenRegistration registration = new CancellationTokenRegistration(this, element, registrationInfo);
         if (!this.IsCancellationRequested)
         {
             return(registration);
         }
         if (!registration.TryDeregister())
         {
             this.WaitForCallbackToComplete(element);
             return(new CancellationTokenRegistration());
         }
     }
     callback(stateForCallback);
     return(new CancellationTokenRegistration());
 }
コード例 #3
0
 // Token: 0x06003E40 RID: 15936 RVA: 0x000E71FC File Offset: 0x000E53FC
 internal CancellationTokenRegistration InternalRegister(Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
 {
     if (AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource)
     {
         this.ThrowIfDisposed();
     }
     if (!this.IsCancellationRequested)
     {
         if (this.m_disposed && !AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource)
         {
             return(default(CancellationTokenRegistration));
         }
         int num = Thread.CurrentThread.ManagedThreadId % CancellationTokenSource.s_nLists;
         CancellationCallbackInfo cancellationCallbackInfo         = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);
         SparselyPopulatedArray <CancellationCallbackInfo>[] array = this.m_registeredCallbacksLists;
         if (array == null)
         {
             SparselyPopulatedArray <CancellationCallbackInfo>[] array2 = new SparselyPopulatedArray <CancellationCallbackInfo> [CancellationTokenSource.s_nLists];
             array = Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, array2, null);
             if (array == null)
             {
                 array = array2;
             }
         }
         SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read <SparselyPopulatedArray <CancellationCallbackInfo> >(ref array[num]);
         if (sparselyPopulatedArray == null)
         {
             SparselyPopulatedArray <CancellationCallbackInfo> value = new SparselyPopulatedArray <CancellationCallbackInfo>(4);
             Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo> >(ref array[num], value, null);
             sparselyPopulatedArray = array[num];
         }
         SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> registrationInfo = sparselyPopulatedArray.Add(cancellationCallbackInfo);
         CancellationTokenRegistration result = new CancellationTokenRegistration(cancellationCallbackInfo, registrationInfo);
         if (!this.IsCancellationRequested)
         {
             return(result);
         }
         if (!result.TryDeregister())
         {
             return(result);
         }
     }
     callback(stateForCallback);
     return(default(CancellationTokenRegistration));
 }
コード例 #4
0
 internal CancellationTokenRegistration InternalRegister(Action <object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
 {
     if (AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource)
     {
         this.ThrowIfDisposed();
     }
     if (!this.IsCancellationRequested)
     {
         if (this.m_disposed && !AppContextSwitches.ThrowExceptionIfDisposedCancellationTokenSource)
         {
             return(new CancellationTokenRegistration());
         }
         int index = Thread.CurrentThread.ManagedThreadId % CancellationTokenSource.s_nLists;
         CancellationCallbackInfo cancellationCallbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);
         SparselyPopulatedArray <CancellationCallbackInfo>[] sparselyPopulatedArrayArray1 = this.m_registeredCallbacksLists;
         if (sparselyPopulatedArrayArray1 == null)
         {
             SparselyPopulatedArray <CancellationCallbackInfo>[] sparselyPopulatedArrayArray2 = new SparselyPopulatedArray <CancellationCallbackInfo> [CancellationTokenSource.s_nLists];
             sparselyPopulatedArrayArray1 = Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, sparselyPopulatedArrayArray2, (SparselyPopulatedArray <CancellationCallbackInfo>[])null) ?? sparselyPopulatedArrayArray2;
         }
         SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray1 = Volatile.Read <SparselyPopulatedArray <CancellationCallbackInfo> >(ref sparselyPopulatedArrayArray1[index]);
         if (sparselyPopulatedArray1 == null)
         {
             SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray2 = new SparselyPopulatedArray <CancellationCallbackInfo>(4);
             Interlocked.CompareExchange <SparselyPopulatedArray <CancellationCallbackInfo> >(ref sparselyPopulatedArrayArray1[index], sparselyPopulatedArray2, (SparselyPopulatedArray <CancellationCallbackInfo>)null);
             sparselyPopulatedArray1 = sparselyPopulatedArrayArray1[index];
         }
         SparselyPopulatedArrayAddInfo <CancellationCallbackInfo> registrationInfo = sparselyPopulatedArray1.Add(cancellationCallbackInfo);
         CancellationTokenRegistration tokenRegistration = new CancellationTokenRegistration(cancellationCallbackInfo, registrationInfo);
         if (!this.IsCancellationRequested || !tokenRegistration.TryDeregister())
         {
             return(tokenRegistration);
         }
     }
     callback(stateForCallback);
     return(new CancellationTokenRegistration());
 }
 internal CancellationTokenRegistration InternalRegister(Action<object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
 {
     this.ThrowIfDisposed();
     if (!this.IsCancellationRequested)
     {
         int index = Thread.CurrentThread.ManagedThreadId % s_nLists;
         CancellationCallbackInfo element = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);
         if (this.m_registeredCallbacksLists == null)
         {
             SparselyPopulatedArray<CancellationCallbackInfo>[] arrayArray = new SparselyPopulatedArray<CancellationCallbackInfo>[s_nLists];
             Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, arrayArray, null);
         }
         if (this.m_registeredCallbacksLists[index] == null)
         {
             SparselyPopulatedArray<CancellationCallbackInfo> array = new SparselyPopulatedArray<CancellationCallbackInfo>(4);
             Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>>(ref this.m_registeredCallbacksLists[index], array, null);
         }
         SparselyPopulatedArrayAddInfo<CancellationCallbackInfo> registrationInfo = this.m_registeredCallbacksLists[index].Add(element);
         CancellationTokenRegistration registration = new CancellationTokenRegistration(this, element, registrationInfo);
         if (!this.IsCancellationRequested)
         {
             return registration;
         }
         if (!registration.TryDeregister())
         {
             this.WaitForCallbackToComplete(element);
             return new CancellationTokenRegistration();
         }
     }
     callback(stateForCallback);
     return new CancellationTokenRegistration();
 }
コード例 #6
0
ファイル: CancellationTokenSource.cs プロジェクト: rmc00/gsf
 internal CancellationTokenRegistration InternalRegister(Action<object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
 {
     this.ThrowIfDisposed();
     if (!this.IsCancellationRequested)
     {
         int num = Thread.CurrentThread.ManagedThreadId % CancellationTokenSource.s_nLists;
         CancellationCallbackInfo cancellationCallbackInfo = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);
         SparselyPopulatedArray<CancellationCallbackInfo>[] array = this.m_registeredCallbacksLists;
         if (array == null)
         {
             SparselyPopulatedArray<CancellationCallbackInfo>[] array2 = new SparselyPopulatedArray<CancellationCallbackInfo>[CancellationTokenSource.s_nLists];
             array = Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>[]>(ref this.m_registeredCallbacksLists, array2, null);
             if (array == null)
             {
                 array = array2;
             }
         }
         SparselyPopulatedArray<CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read<SparselyPopulatedArray<CancellationCallbackInfo>>(ref array[num]);
         if (sparselyPopulatedArray == null)
         {
             SparselyPopulatedArray<CancellationCallbackInfo> value = new SparselyPopulatedArray<CancellationCallbackInfo>(4);
             Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>>(ref array[num], value, null);
             sparselyPopulatedArray = array[num];
         }
         SparselyPopulatedArrayAddInfo<CancellationCallbackInfo> registrationInfo = sparselyPopulatedArray.Add(cancellationCallbackInfo);
         CancellationTokenRegistration result = new CancellationTokenRegistration(cancellationCallbackInfo, registrationInfo);
         if (!this.IsCancellationRequested)
         {
             return result;
         }
         if (!result.TryDeregister())
         {
             return result;
         }
     }
     callback(stateForCallback);
     return default(CancellationTokenRegistration);
 }
コード例 #7
0
 internal CancellationTokenRegistration InternalRegister(Action<object> callback, object stateForCallback, SynchronizationContext targetSyncContext, ExecutionContext executionContext)
 {
     ThrowIfDisposed();
     if (!IsCancellationRequested)
     {
         var index = Thread.CurrentThread.ManagedThreadId % _nLists;
         var element = new CancellationCallbackInfo(callback, stateForCallback, targetSyncContext, executionContext, this);
         var registeredCallbacksLists = _registeredCallbacksLists;
         if (registeredCallbacksLists == null)
         {
             var arrayArray2 = new SparselyPopulatedArray<CancellationCallbackInfo>[_nLists];
             registeredCallbacksLists = Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>[]>(ref _registeredCallbacksLists, arrayArray2, null);
             if (registeredCallbacksLists == null)
                 registeredCallbacksLists = arrayArray2;
         }
         var array = Volatile.Read<SparselyPopulatedArray<CancellationCallbackInfo>>(ref registeredCallbacksLists[index]);
         if (array == null)
         {
             var array2 = new SparselyPopulatedArray<CancellationCallbackInfo>(4);
             Interlocked.CompareExchange<SparselyPopulatedArray<CancellationCallbackInfo>>(ref registeredCallbacksLists[index], array2, null);
             array = registeredCallbacksLists[index];
         }
         var registrationInfo = array.Add(element);
         var registration = new CancellationTokenRegistration(element, registrationInfo);
         if (!IsCancellationRequested)
             return registration;
         if (!registration.TryDeregister())
             return registration;
     }
     callback(stateForCallback);
     return new CancellationTokenRegistration();
 }