public void Dispose()
        {
            if (_signal == null)
            {
                return;
            }

            BCLDebug.Assert(Thread.CurrentThread == _signal.Thread, "You called Dispose on the wrong thread, or reused your cancellation signal?");
            List <CancellationSignal> signals = _signal.Thread.CancellationSignals;

            bool tookLock = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                Monitor.ReliableEnter(signals, out tookLock);
                CancellationSignal s = signals[signals.Count - 1];
                signals.RemoveAt(signals.Count - 1);
                if (!Object.ReferenceEquals(s, _signal))
                {
                    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CancellationRegionLeak"));
                }
                _signal.Thread = null;
                _signal        = null;
            }
            finally {
                if (tookLock)
                {
                    Monitor.Exit(signals);
                }
                Thread.EndThreadAffinity();
            }
        }
        public static void PollForCancellation()
        {
            Thread t = Thread.CurrentThread;
            // Don't go through the property on Thread, but access the field
            // directly.  We don't want to create the stack if no one in the
            // thread is using cancellation.
            List <CancellationSignal> signals = t.m_CancellationSignals;

            if (signals != null)
            {
                bool tookLock = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try {
                    Monitor.ReliableEnter(signals, out tookLock);
                    if (signals.Count > 0)
                    {
                        if (signals[signals.Count - 1].CancelRequested)
                        {
                            throw new OperationCanceledException();
                        }
                    }
                }
                finally {
                    if (tookLock)
                    {
                        Monitor.Exit(signals);
                    }
                }
            }
        }
示例#3
0
 public static void Enter(object obj, ref bool lockTaken)
 {
     if (lockTaken)
     {
         Monitor.ThrowLockTakenException();
     }
     Monitor.ReliableEnter(obj, ref lockTaken);
 }