public void RegisterCallback(Action onCacelledCallback) { if (IsCanceled) { onCacelledCallback(); return; } var sw = new SpinWaitStolen(); while (true) { var wasInstance = _onCancelledCallbacks; var newInstance = wasInstance + onCacelledCallback; if (Interlocked.CompareExchange(ref _onCancelledCallbacks, newInstance, wasInstance) == wasInstance) break; sw.SpinOnce(); } }
internal bool TryEnter(bool threadBlockingAllowed = false) { const int spinCount = 1000; if (!threadBlockingAllowed) return Interlocked.CompareExchange(ref _waitersCount, 1, 0) == 0; var spinWait = new SpinWaitStolen(); for (var i = 0; i < spinCount; i++) { if (Interlocked.CompareExchange(ref _waitersCount, 1, 0) == 0) return true; spinWait.SpinOnce(); } if (Interlocked.Increment(ref _waitersCount) == 1) return true; _kernelLock.WaitOne(); return true; }