コード例 #1
0
        /// <summary>
        /// Waits until predicate estimates to true or cancellation received or dispose happened
        /// </summary>
        private bool WaitUntilPredicate <TState>(WaitPredicate <TState> predicate, TState state, uint startTime, int timeout, CancellationToken token)
        {
            TurboContract.Assert(predicate != null, conditionString: "predicate != null");

            int remainingWaitMilliseconds = Timeout.Infinite;

            while (true)
            {
                if (token.IsCancellationRequested || _isDisposed)
                {
                    return(false);
                }

                if (timeout != Timeout.Infinite)
                {
                    remainingWaitMilliseconds = TimeoutHelper.UpdateTimeout(startTime, timeout);
                    if (remainingWaitMilliseconds <= 0)
                    {
                        return(false);
                    }
                }

                if (!Monitor.Wait(this, remainingWaitMilliseconds))
                {
                    return(false);
                }

                if (predicate.Invoke(state))
                {
                    return(true);
                }
            }
        }
コード例 #2
0
        private bool WaitUntilPredicate <TState>(ref bool internalLockTaken, ref bool externalLockTaken, WaitPredicate <TState> predicate, TState state, uint startTime, int timeout, CancellationToken token)
        {
            TurboContract.Requires(internalLockTaken, "internalLockTaken == false");
            TurboContract.Requires(externalLockTaken, "externalLockTaken == false");
            TurboContract.Requires(predicate != null, conditionString: "predicate != null");

            int  remainingWaitMilliseconds = Timeout.Infinite;
            bool recursiveLockChecked      = false;

            while (true)
            {
                if (token.IsCancellationRequested || _isDisposed)
                {
                    return(false);
                }

                if (timeout != Timeout.Infinite)
                {
                    remainingWaitMilliseconds = TimeoutHelper.UpdateTimeout(startTime, timeout);
                    if (remainingWaitMilliseconds <= 0)
                    {
                        return(false);
                    }
                }

                ExitLock(_externalLock, ref externalLockTaken);

                if (!recursiveLockChecked && Monitor.IsEntered(_externalLock)) // Sanity check
                {
                    throw new SynchronizationLockException("Recursive lock is not supported");
                }
                recursiveLockChecked = true;

                if (!Monitor.Wait(_internalLock, remainingWaitMilliseconds))
                {
                    return(false);
                }

                try
                {
                    ExitLock(_internalLock, ref internalLockTaken);
                    EnterLock(_externalLock, ref externalLockTaken);

                    if (predicate.Invoke(state))
                    {
                        return(true);
                    }
                }
                finally
                {
                    EnterLock(_internalLock, ref internalLockTaken);
                }
            }
        }
コード例 #3
0
        private bool WaitUntilPredicate <TState>(ref bool internalLockTaken, ref bool externalLockTaken, WaitPredicate <TState> predicate, TState state)
        {
            TurboContract.Requires(internalLockTaken, "internalLockTaken == false");
            TurboContract.Requires(externalLockTaken, "externalLockTaken == false");
            TurboContract.Requires(predicate != null, conditionString: "predicate != null");

            int remainingWaitMilliseconds = Timeout.Infinite;

            while (true)
            {
                if (_token.IsCancellationRequested || _sourceWaiter.IsDisposed)
                {
                    return(false);
                }

                if (_timeout != Timeout.Infinite)
                {
                    remainingWaitMilliseconds = TimeoutHelper.UpdateTimeout(_startTime, _timeout);
                    if (remainingWaitMilliseconds <= 0)
                    {
                        return(false);
                    }
                }

                ExitLock(_sourceWaiter.ExternalLock, ref externalLockTaken);

                if (!Monitor.Wait(_sourceWaiter.InternalLock, remainingWaitMilliseconds))
                {
                    return(false);
                }

                try
                {
                    ExitLock(_sourceWaiter.InternalLock, ref internalLockTaken);
                    EnterLock(_sourceWaiter.ExternalLock, ref externalLockTaken);

                    if (predicate.Invoke(state))
                    {
                        return(true);
                    }
                }
                finally
                {
                    EnterLock(_sourceWaiter.InternalLock, ref internalLockTaken);
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Blocks the current thread until predicate estimates as True
        /// </summary>
        /// <typeparam name="TState">Type of the state object</typeparam>
        /// <param name="predicate">Predicate that should return True to complete waiting</param>
        /// <param name="state">State object for the predicate</param>
        /// <returns>True if predicate evaluates to True</returns>
        /// <exception cref="ArgumentNullException">predicate is null</exception>
        /// <exception cref="ObjectDisposedException">ConditionVariable was disposed</exception>
        /// <exception cref="OperationCanceledException">Cancellation happened</exception>
        /// <exception cref="OperationInterruptedException">Waiting was interrupted by Dispose</exception>
        public bool Wait<TState>(WaitPredicate<TState> predicate, TState state)
        {
            if (predicate == null)
                throw new ArgumentNullException(nameof(predicate));
            if (_sourceWaiter == null)
                throw new ObjectDisposedException(nameof(MonitorWaiter), "Lock section has exited");
            if (_sourceWaiter.IsDisposed)
                throw new ObjectDisposedException(nameof(MonitorObject), $"MonitorObject '{_sourceWaiter.Name}' was disposed");
            if (_token.IsCancellationRequested)
                throw new OperationCanceledException(_token);

            Debug.Assert(_sourceWaiter.IsEntered());

            if (predicate(state))
                return true;
            else if (_timeout == 0)
                return false;

            int remainingWaitMilliseconds = Timeout.Infinite;

            while (!_token.IsCancellationRequested && !_sourceWaiter.IsDisposed)
            {
                if (_timeout != Timeout.Infinite)
                {
                    remainingWaitMilliseconds = TimeoutHelper.UpdateTimeout(_startTime, _timeout);
                    if (remainingWaitMilliseconds <= 0)
                        break;
                }

                if (!Monitor.Wait(_sourceWaiter, remainingWaitMilliseconds))
                    break;

                if (predicate.Invoke(state))
                    return true;
            }


            // Check if cancellation or dispose was the reasons of the signal
            if (_token.IsCancellationRequested)
                throw new OperationCanceledException(_token);
            if (_sourceWaiter.IsDisposed)
                throw new OperationInterruptedException("Wait was interrupted by Dispose", new ObjectDisposedException(nameof(MonitorObject), $"MonitorObject '{_sourceWaiter.Name}' was disposed"));

            // Final check for predicate
            return predicate(state);
        }