Пример #1
0
        private void CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments args)
        {
            CancellationCallbackInfo cancellationCallbackInfo = args.m_currArrayFragment.SafeAtomicRemove(args.m_currArrayIndex, this.m_executingCallback);

            if (cancellationCallbackInfo == this.m_executingCallback)
            {
                if (cancellationCallbackInfo.TargetExecutionContext != null)
                {
                    cancellationCallbackInfo.CancellationTokenSource.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                }
                cancellationCallbackInfo.ExecuteCallback();
            }
        }
        private void CancellationCallbackCoreWork_OnSyncContext(object obj)
        {
            CancellationCallbackCoreWorkArguments arguments = (CancellationCallbackCoreWorkArguments)obj;
            CancellationCallbackInfo info = arguments.m_currArrayFragment.SafeAtomicRemove(arguments.m_currArrayIndex, this.m_executingCallback);

            if (info == this.m_executingCallback)
            {
                if (info.TargetExecutionContext != null)
                {
                    info.CancellationTokenSource.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                }
                info.ExecuteCallback();
            }
        }
        // The main callback work that executes on the target synchronization context
        private void CancellationCallbackCoreWork_OnSyncContext(object obj)
        {
            CancellationCallbackCoreWorkArguments args = (CancellationCallbackCoreWorkArguments)obj;

            // now remove the intended callback..and ensure that it worked.
            // otherwise the callback has disappeared in the interim and we can immediately return.
            CancellationCallbackInfo callback = args.m_currArrayFragment.SafeAtomicRemove(args.m_currArrayIndex, m_executingCallback);

            if (callback == m_executingCallback)
            {
                if (callback.TargetExecutionContext != null)
                {
                    // we are running via a custom sync context, so update the executing threadID
                    callback.CancellationTokenSource.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                }
                callback.ExecuteCallback();
            }
        }
Пример #4
0
        private void ExecuteCallbackHandlers(bool throwOnFirstException)
        {
            List <Exception> exceptionList = (List <Exception>)null;

            SparselyPopulatedArray <CancellationCallbackInfo>[] sparselyPopulatedArrayArray = this.m_registeredCallbacksLists;
            if (sparselyPopulatedArrayArray == null)
            {
                Interlocked.Exchange(ref this.m_state, 3);
            }
            else
            {
                try
                {
                    for (int index = 0; index < sparselyPopulatedArrayArray.Length; ++index)
                    {
                        SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read <SparselyPopulatedArray <CancellationCallbackInfo> >(ref sparselyPopulatedArrayArray[index]);
                        if (sparselyPopulatedArray != null)
                        {
                            for (SparselyPopulatedArrayFragment <CancellationCallbackInfo> currArrayFragment = sparselyPopulatedArray.Tail; currArrayFragment != null; currArrayFragment = currArrayFragment.Prev)
                            {
                                for (int currArrayIndex = currArrayFragment.Length - 1; currArrayIndex >= 0; --currArrayIndex)
                                {
                                    this.m_executingCallback = currArrayFragment[currArrayIndex];
                                    if (this.m_executingCallback != null)
                                    {
                                        CancellationCallbackCoreWorkArguments args = new CancellationCallbackCoreWorkArguments(currArrayFragment, currArrayIndex);
                                        try
                                        {
                                            if (this.m_executingCallback.TargetSyncContext != null)
                                            {
                                                this.m_executingCallback.TargetSyncContext.Send(new SendOrPostCallback(this.CancellationCallbackCoreWork_OnSyncContext), (object)args);
                                                this.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                                            }
                                            else
                                            {
                                                this.CancellationCallbackCoreWork(args);
                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            if (throwOnFirstException)
                                            {
                                                throw;
                                            }
                                            else
                                            {
                                                if (exceptionList == null)
                                                {
                                                    exceptionList = new List <Exception>();
                                                }
                                                exceptionList.Add(ex);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    this.m_state             = 3;
                    this.m_executingCallback = (CancellationCallbackInfo)null;
                    Thread.MemoryBarrier();
                }
                if (exceptionList != null)
                {
                    throw new AggregateException((IEnumerable <Exception>)exceptionList);
                }
            }
        }
        /// <summary>
        /// Invoke the Canceled event.
        /// </summary>
        /// <remarks>
        /// The handlers are invoked synchronously in LIFO order.
        /// </remarks>
        private void ExecuteCallbackHandlers(bool throwOnFirstException)
        {
            Contract.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true");
            Contract.Assert(ThreadIDExecutingCallbacks != -1, "ThreadIDExecutingCallbacks should have been set.");

            // Design decision: call the delegates in LIFO order so that callbacks fire 'deepest first'.
            // This is intended to help with nesting scenarios so that child enlisters cancel before their parents.
            List <Exception> exceptionList = null;

            SparselyPopulatedArray <CancellationCallbackInfo>[] callbackLists = m_registeredCallbacksLists;

            // If there are no callbacks to run, we can safely exit.  Any races to lazy initialize it
            // will see IsCancellationRequested and will then run the callback themselves.
            if (callbackLists == null)
            {
                Interlocked.Exchange(ref m_state, NOTIFYINGCOMPLETE);
                return;
            }

            try
            {
                for (int index = 0; index < callbackLists.Length; index++)
                {
                    SparselyPopulatedArray <CancellationCallbackInfo> list = callbackLists[index];
                    if (list != null)
                    {
                        SparselyPopulatedArrayFragment <CancellationCallbackInfo> currArrayFragment = list.Tail;

                        while (currArrayFragment != null)
                        {
                            for (int i = currArrayFragment.Length - 1; i >= 0; i--)
                            {
                                // 1a. publish the indended callback, to ensure ctr.Dipose can tell if a wait is necessary.
                                // 1b. transition to the target syncContext and continue there..
                                //  On the target SyncContext.
                                //   2. actually remove the callback
                                //   3. execute the callback
                                // re:#2 we do the remove on the syncCtx so that we can be sure we have control of the syncCtx before
                                //        grabbing the callback.  This prevents a deadlock if ctr.Dispose() might run on the syncCtx too.
                                m_executingCallback = currArrayFragment[i];
                                if (m_executingCallback != null)
                                {
                                    //Transition to the target sync context (if necessary), and continue our work there.
                                    CancellationCallbackCoreWorkArguments args = new CancellationCallbackCoreWorkArguments(currArrayFragment, i);

                                    // marshal exceptions: either aggregate or perform an immediate rethrow
                                    // We assume that syncCtx.Send() has forwarded on user exceptions when appropriate.
                                    try
                                    {
                                        if (m_executingCallback.TargetSyncContext != null)
                                        {
                                            m_executingCallback.TargetSyncContext.Send(CancellationCallbackCoreWork_OnSyncContext, args);
                                            // CancellationCallbackCoreWork_OnSyncContext may have altered ThreadIDExecutingCallbacks, so reset it.
                                            ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                                        }
                                        else
                                        {
                                            CancellationCallbackCoreWork_OnSyncContext(args);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        if (throwOnFirstException)
                                        {
                                            throw;
                                        }

                                        // Otherwise, log it and proceed.
                                        if (exceptionList == null)
                                        {
                                            exceptionList = new List <Exception>();
                                        }
                                        exceptionList.Add(ex);
                                    }
                                }
                            }

                            currArrayFragment = currArrayFragment.Prev;
                        }
                    }
                }
            }
            finally
            {
                m_state             = NOTIFYINGCOMPLETE;
                m_executingCallback = null;
                Thread.MemoryBarrier(); // for safety, prevent reorderings crossing this point and seeing inconsistent state.
            }

            if (exceptionList != null)
            {
                Contract.Assert(exceptionList.Count > 0, "Expected exception count > 0");
                throw new AggregateException(exceptionList);
            }
        }
Пример #6
0
        private void ExecuteCallbackHandlers(bool throwOnFirstException)
        {
            List <Exception> list = null;

            SparselyPopulatedArray <CancellationCallbackInfo>[] registeredCallbacksLists = this.m_registeredCallbacksLists;
            if (registeredCallbacksLists == null)
            {
                Interlocked.Exchange(ref this.m_state, 3);
                return;
            }
            try
            {
                for (int i = 0; i < registeredCallbacksLists.Length; i++)
                {
                    SparselyPopulatedArray <CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read <SparselyPopulatedArray <CancellationCallbackInfo> >(ref registeredCallbacksLists[i]);
                    if (sparselyPopulatedArray != null)
                    {
                        for (SparselyPopulatedArrayFragment <CancellationCallbackInfo> sparselyPopulatedArrayFragment = sparselyPopulatedArray.Tail; sparselyPopulatedArrayFragment != null; sparselyPopulatedArrayFragment = sparselyPopulatedArrayFragment.Prev)
                        {
                            for (int j = sparselyPopulatedArrayFragment.Length - 1; j >= 0; j--)
                            {
                                this.m_executingCallback = sparselyPopulatedArrayFragment[j];
                                if (this.m_executingCallback != null)
                                {
                                    CancellationCallbackCoreWorkArguments cancellationCallbackCoreWorkArguments = new CancellationCallbackCoreWorkArguments(sparselyPopulatedArrayFragment, j);
                                    try
                                    {
                                        if (this.m_executingCallback.TargetSyncContext != null)
                                        {
                                            this.m_executingCallback.TargetSyncContext.Send(new SendOrPostCallback(this.CancellationCallbackCoreWork_OnSyncContext), cancellationCallbackCoreWorkArguments);
                                            this.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                                        }
                                        else
                                        {
                                            this.CancellationCallbackCoreWork(cancellationCallbackCoreWorkArguments);
                                        }
                                    }
                                    catch (Exception item)
                                    {
                                        if (throwOnFirstException)
                                        {
                                            throw;
                                        }
                                        if (list == null)
                                        {
                                            list = new List <Exception>();
                                        }
                                        list.Add(item);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                this.m_state             = 3;
                this.m_executingCallback = null;
                Thread.MemoryBarrier();
            }
            if (list != null)
            {
                throw new AggregateException(list);
            }
        }
 private void ExecuteCallbackHandlers(bool throwOnFirstException)
 {
     List<Exception> innerExceptions = null;
     SparselyPopulatedArray<CancellationCallbackInfo>[] registeredCallbacksLists = this.m_registeredCallbacksLists;
     if (registeredCallbacksLists == null)
     {
         Interlocked.Exchange(ref this.m_state, 3);
     }
     else
     {
         try
         {
             for (int i = 0; i < registeredCallbacksLists.Length; i++)
             {
                 SparselyPopulatedArray<CancellationCallbackInfo> array = registeredCallbacksLists[i];
                 if (array != null)
                 {
                     for (SparselyPopulatedArrayFragment<CancellationCallbackInfo> fragment = array.Tail; fragment != null; fragment = fragment.Prev)
                     {
                         for (int j = fragment.Length - 1; j >= 0; j--)
                         {
                             this.m_executingCallback = fragment[j];
                             if (this.m_executingCallback != null)
                             {
                                 CancellationCallbackCoreWorkArguments state = new CancellationCallbackCoreWorkArguments(fragment, j);
                                 try
                                 {
                                     if (this.m_executingCallback.TargetSyncContext != null)
                                     {
                                         this.m_executingCallback.TargetSyncContext.Send(new SendOrPostCallback(this.CancellationCallbackCoreWork_OnSyncContext), state);
                                         this.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                                     }
                                     else
                                     {
                                         this.CancellationCallbackCoreWork_OnSyncContext(state);
                                     }
                                 }
                                 catch (Exception exception)
                                 {
                                     if (throwOnFirstException)
                                     {
                                         throw;
                                     }
                                     if (innerExceptions == null)
                                     {
                                         innerExceptions = new List<Exception>();
                                     }
                                     innerExceptions.Add(exception);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         finally
         {
             this.m_state = 3;
             this.m_executingCallback = null;
             Thread.MemoryBarrier();
         }
         if (innerExceptions != null)
         {
             throw new AggregateException(innerExceptions);
         }
     }
 }
Пример #8
0
 private void CancellationCallbackCoreWork(CancellationCallbackCoreWorkArguments args)
 {
     CancellationCallbackInfo cancellationCallbackInfo = args.m_currArrayFragment.SafeAtomicRemove(args.m_currArrayIndex, this.m_executingCallback);
     if (cancellationCallbackInfo == this.m_executingCallback)
     {
         if (cancellationCallbackInfo.TargetExecutionContext != null)
         {
             cancellationCallbackInfo.CancellationTokenSource.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
         }
         cancellationCallbackInfo.ExecuteCallback();
     }
 }
Пример #9
0
 private void ExecuteCallbackHandlers(bool throwOnFirstException)
 {
     List<Exception> list = null;
     SparselyPopulatedArray<CancellationCallbackInfo>[] registeredCallbacksLists = this.m_registeredCallbacksLists;
     if (registeredCallbacksLists == null)
     {
         Interlocked.Exchange(ref this.m_state, 3);
         return;
     }
     try
     {
         for (int i = 0; i < registeredCallbacksLists.Length; i++)
         {
             SparselyPopulatedArray<CancellationCallbackInfo> sparselyPopulatedArray = Volatile.Read<SparselyPopulatedArray<CancellationCallbackInfo>>(ref registeredCallbacksLists[i]);
             if (sparselyPopulatedArray != null)
             {
                 for (SparselyPopulatedArrayFragment<CancellationCallbackInfo> sparselyPopulatedArrayFragment = sparselyPopulatedArray.Tail; sparselyPopulatedArrayFragment != null; sparselyPopulatedArrayFragment = sparselyPopulatedArrayFragment.Prev)
                 {
                     for (int j = sparselyPopulatedArrayFragment.Length - 1; j >= 0; j--)
                     {
                         this.m_executingCallback = sparselyPopulatedArrayFragment[j];
                         if (this.m_executingCallback != null)
                         {
                             CancellationCallbackCoreWorkArguments cancellationCallbackCoreWorkArguments = new CancellationCallbackCoreWorkArguments(sparselyPopulatedArrayFragment, j);
                             try
                             {
                                 if (this.m_executingCallback.TargetSyncContext != null)
                                 {
                                     this.m_executingCallback.TargetSyncContext.Send(new SendOrPostCallback(this.CancellationCallbackCoreWork_OnSyncContext), cancellationCallbackCoreWorkArguments);
                                     this.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                                 }
                                 else
                                 {
                                     this.CancellationCallbackCoreWork(cancellationCallbackCoreWorkArguments);
                                 }
                             }
                             catch (Exception item)
                             {
                                 if (throwOnFirstException)
                                 {
                                     throw;
                                 }
                                 if (list == null)
                                 {
                                     list = new List<Exception>();
                                 }
                                 list.Add(item);
                             }
                         }
                     }
                 }
             }
         }
     }
     finally
     {
         this.m_state = 3;
         this.m_executingCallback = null;
         Thread.MemoryBarrier();
     }
     if (list != null)
     {
         throw new AggregateException(list);
     }
 }
        private void ExecuteCallbackHandlers(bool throwOnFirstException)
        {
            List <Exception> innerExceptions = null;

            SparselyPopulatedArray <CancellationCallbackInfo>[] registeredCallbacksLists = this.m_registeredCallbacksLists;
            if (registeredCallbacksLists == null)
            {
                Interlocked.Exchange(ref this.m_state, 3);
            }
            else
            {
                try
                {
                    for (int i = 0; i < registeredCallbacksLists.Length; i++)
                    {
                        SparselyPopulatedArray <CancellationCallbackInfo> array = registeredCallbacksLists[i];
                        if (array != null)
                        {
                            for (SparselyPopulatedArrayFragment <CancellationCallbackInfo> fragment = array.Tail; fragment != null; fragment = fragment.Prev)
                            {
                                for (int j = fragment.Length - 1; j >= 0; j--)
                                {
                                    this.m_executingCallback = fragment[j];
                                    if (this.m_executingCallback != null)
                                    {
                                        CancellationCallbackCoreWorkArguments state = new CancellationCallbackCoreWorkArguments(fragment, j);
                                        try
                                        {
                                            if (this.m_executingCallback.TargetSyncContext != null)
                                            {
                                                this.m_executingCallback.TargetSyncContext.Send(new SendOrPostCallback(this.CancellationCallbackCoreWork_OnSyncContext), state);
                                                this.ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
                                            }
                                            else
                                            {
                                                this.CancellationCallbackCoreWork_OnSyncContext(state);
                                            }
                                        }
                                        catch (Exception exception)
                                        {
                                            if (throwOnFirstException)
                                            {
                                                throw;
                                            }
                                            if (innerExceptions == null)
                                            {
                                                innerExceptions = new List <Exception>();
                                            }
                                            innerExceptions.Add(exception);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    this.m_state             = 3;
                    this.m_executingCallback = null;
                    Thread.MemoryBarrier();
                }
                if (innerExceptions != null)
                {
                    throw new AggregateException(innerExceptions);
                }
            }
        }