예제 #1
0
        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();
            }
        }
예제 #2
0
        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;
        }