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); } } } }
public static void Enter(object obj, ref bool lockTaken) { if (lockTaken) { Monitor.ThrowLockTakenException(); } Monitor.ReliableEnter(obj, ref lockTaken); }