コード例 #1
0
        private bool WaitExtracted(int millisecondsTimeout)
        {
            var spinWait  = new SpinWait();
            var spinCount = SpinCount;

            if (IsSet)
            {
                return(true);
            }

            var start = ThreadingHelper.TicksNow();

            while (true)
            {
                if (IsSet)
                {
                    return(true);
                }

                var elapsed = ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start);
                if (elapsed >= millisecondsTimeout)
                {
                    return(false);
                }

                if (spinCount > 0)
                {
                    spinCount--;
                    spinWait.SpinOnce();
                    continue;
                }

                var handle    = GetOrCreateWaitHandle();
                var remaining = millisecondsTimeout - (int)elapsed;
                return(remaining > 0 && handle.WaitOne(remaining));
            }
        }
コード例 #2
0
        public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            CheckDisposed();
            if (millisecondsTimeout < -1)
            {
                throw new ArgumentOutOfRangeException("millisecondsTimeout");
            }
            cancellationToken.ThrowIfCancellationRequested();
            GC.KeepAlive(cancellationToken.WaitHandle);
            if (millisecondsTimeout == -1)
            {
                var spinWait = new SpinWait();
                while (!TryEnter())
                {
                    spinWait.SpinOnce();
                }
                return(true);
            }
            var start     = ThreadingHelper.TicksNow();
            var remaining = millisecondsTimeout;

            while (_event.Wait(remaining, cancellationToken))
            {
                // The thread is not allowed here unless there is room in the semaphore
                if (TryEnter())
                {
                    return(true);
                }
                remaining = (int)(millisecondsTimeout - ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start));
                if (remaining <= 0)
                {
                    break;
                }
            }
            // Time out
            return(false);
        }
コード例 #3
0
        public void Wait()
        {
            if (Thread.VolatileRead(ref _state) == -1)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
            var count = 0;

            if (!IsSet)
            {
                var start = ThreadingHelper.TicksNow();
retry:
                if (!IsSet)
                {
                    if (ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start) < INT_LongTimeOutHint)
                    {
                        ThreadingHelper.SpinOnce(ref count);
                        goto retry;
                    }
                    var handle = RetriveWaitHandle();
                    handle.WaitOne();
                }
            }
        }
コード例 #4
0
        public static int TryTakeFromAny(BlockingCollection <T>[] collections, out T item, int millisecondsTimeout, CancellationToken cancellationToken)
        {
            if (collections == null)
            {
                throw new ArgumentNullException(nameof(collections));
            }

            if (collections.Length == 0)
            {
                throw new ArgumentException("The collections argument is a 0-length array", nameof(collections));
            }

            var waitHandles = new WaitHandle[collections.Length + 1];

            for (var index = 0; index < collections.Length; index++)
            {
                var collection = collections[index];
                if (collection == null)
                {
                    throw new ArgumentException("The collections argument contains a null element", nameof(collections));
                }

                waitHandles[index] = collection.Data.WaitHandle;
                if (collection.IsAddingCompleted)
                {
                    throw new ArgumentException("At least one of collections has been marked as complete for adding.", nameof(collections));
                }

                if (collection.TryTake(out item, 0, cancellationToken))
                {
                    return(index);
                }
            }

            waitHandles[collections.Length] = cancellationToken.WaitHandle;
            if (millisecondsTimeout == -1)
            {
                while (true)
                {
                    WaitHandle.WaitAny(waitHandles);
                    cancellationToken.ThrowIfCancellationRequested();
                    for (var index = 0; index < collections.Length; index++)
                    {
                        var collection = collections[index];
                        if (collection.IsAddingCompleted)
                        {
                            throw new ArgumentException("At least one of collections has been marked as complete for adding.", nameof(collections));
                        }

                        if (collection.TryTake(out item, 0, cancellationToken))
                        {
                            return(index);
                        }
                    }
                }
            }

            var start     = ThreadingHelper.TicksNow();
            var remaining = millisecondsTimeout;

            while (true)
            {
                WaitHandle.WaitAny(waitHandles, remaining);
                cancellationToken.ThrowIfCancellationRequested();
                for (var index = 0; index < collections.Length; index++)
                {
                    var collection = collections[index];
                    if (collection.IsAddingCompleted)
                    {
                        throw new ArgumentException("At least one of collections has been marked as complete for adding.", nameof(collections));
                    }

                    if (collection.TryTake(out item, 0, cancellationToken))
                    {
                        return(index);
                    }

                    remaining = (int)(millisecondsTimeout - ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start));
                    if (remaining <= 0)
                    {
                        return(-1);
                    }
                }
            }
        }
コード例 #5
0
        private bool WaitExtracted(int millisecondsTimeout, CancellationToken cancellationToken)
        {
            var count = 0;

            if (IsSet)
            {
                return(true);
            }
            var start = ThreadingHelper.TicksNow();

            if (millisecondsTimeout > INT_LongTimeOutHint)
            {
retry_longTimeout:
                if (IsSet)
                {
                    return(true);
                }
                cancellationToken.ThrowIfCancellationRequested();
                GC.KeepAlive(cancellationToken.WaitHandle);
                var elapsed = ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start);
                if (elapsed < millisecondsTimeout)
                {
                    if (elapsed < INT_LongTimeOutHint)
                    {
                        ThreadingHelper.SpinOnce(ref count);
                        goto retry_longTimeout;
                    }
                    var handle    = RetriveWaitHandle();
                    var remaining = millisecondsTimeout - (int)elapsed;
                    if (remaining > 0)
                    {
                        var result = WaitHandle.WaitAny
                                     (
                            new[]
                        {
                            handle,
                            cancellationToken.WaitHandle
                        },
                            remaining
                                     );
                        cancellationToken.ThrowIfCancellationRequested();
                        GC.KeepAlive(cancellationToken.WaitHandle);
                        return(result != WaitHandle.WaitTimeout);
                    }
                }
                cancellationToken.ThrowIfCancellationRequested();
                GC.KeepAlive(cancellationToken.WaitHandle);
            }
            else
            {
retry_shortTimeout:
                if (IsSet)
                {
                    return(true);
                }
                cancellationToken.ThrowIfCancellationRequested();
                GC.KeepAlive(cancellationToken.WaitHandle);
                var elapsed = ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start);
                if (elapsed < millisecondsTimeout)
                {
                    ThreadingHelper.SpinOnce(ref count);
                    goto retry_shortTimeout;
                }
                cancellationToken.ThrowIfCancellationRequested();
                GC.KeepAlive(cancellationToken.WaitHandle);
            }
            return(false);
        }
コード例 #6
0
        public bool Wait(int milliseconds, CancellationToken cancellationToken)
        {
            if (milliseconds < -1)
            {
                throw new ArgumentOutOfRangeException("milliseconds");
            }
            if (milliseconds == -1)
            {
                Wait(cancellationToken);
                return(true);
            }
            var start = ThreadingHelper.TicksNow();

            do
            {
                CancellationCheck(cancellationToken);
                switch (Status)
                {
                case TaskStatus.WaitingForActivation:
                    WaitAntecedent(cancellationToken, milliseconds, start);
                    ExecutingTaskScheduler.InernalTryExecuteTaskInline(this, true);
                    break;

                case TaskStatus.Created:
                case TaskStatus.WaitingToRun:
                case TaskStatus.Running:
                case TaskStatus.WaitingForChildrenToComplete:
                    var waitHandle = _waitHandle.Value;
                    if (_waitHandle.IsAlive)
                    {
                        waitHandle.Wait
                        (
                            TimeSpan.FromMilliseconds
                            (
                                milliseconds - ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start)
                            ),
                            cancellationToken
                        );
                    }
                    break;

                case TaskStatus.RanToCompletion:
                    return(true);

                case TaskStatus.Canceled:
                    ThrowIfExceptional(true);
                    return(true);

                case TaskStatus.Faulted:
                    ThrowIfExceptional(true);
                    return(true);
                }
            } while (ThreadingHelper.Milliseconds(ThreadingHelper.TicksNow() - start) < milliseconds);
            switch (Status)
            {
            case TaskStatus.RanToCompletion:
                return(true);

            case TaskStatus.Canceled:
                ThrowIfExceptional(true);
                return(true);

            case TaskStatus.Faulted:
                ThrowIfExceptional(true);
                return(true);

            default:
                return(false);
            }
        }