public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) // TODO: Test coverage? { if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("millisecondsTimeout"); } if (millisecondsTimeout == -1) { return(WaitAsync(cancellationToken).ContinueWith(_ => true)); } if (cancellationToken.IsCancellationRequested) { return(Task <bool> .FromCancellation(cancellationToken)); } CheckDisposed(); var source = new TaskCompletionSource <bool>(); if (Wait(0, cancellationToken)) { source.SetResult(true); return(source.Task); } Thread.MemoryBarrier(); Theraot.Threading.Timeout.Launch(() => source.SetResult(false), millisecondsTimeout, cancellationToken); cancellationToken.Register(() => source.SetCanceled()); _asyncWaiters.Add(source); return(source.Task); }
public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { this.CheckDispose(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("totalMilliSeconds", millisecondsTimeout, SemaphoreSlim.GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCancellation <bool>(cancellationToken)); } object lockObj = this.m_lockObj; Task <bool> result; lock (lockObj) { if (this.m_currentCount > 0) { this.m_currentCount--; if (this.m_waitHandle != null && this.m_currentCount == 0) { this.m_waitHandle.Reset(); } result = SemaphoreSlim.s_trueTask; } else { SemaphoreSlim.TaskNode taskNode = this.CreateAndAddAsyncWaiter(); result = ((millisecondsTimeout == -1 && !cancellationToken.CanBeCanceled) ? taskNode : this.WaitUntilCountOrTimeoutAsync(taskNode, millisecondsTimeout, cancellationToken)); } } return(result); }
public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { this.CheckDispose(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException("totalMilliSeconds", (object)millisecondsTimeout, SemaphoreSlim.GetResourceString("SemaphoreSlim_Wait_TimeoutWrong")); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCancellation <bool>(cancellationToken)); } lock (this.m_lockObj) { if (this.m_currentCount > 0) { this.m_currentCount = this.m_currentCount - 1; if (this.m_waitHandle != null && this.m_currentCount == 0) { this.m_waitHandle.Reset(); } return(SemaphoreSlim.s_trueTask); } SemaphoreSlim.TaskNode local_3 = this.CreateAndAddAsyncWaiter(); return(millisecondsTimeout != -1 || cancellationToken.CanBeCanceled ? this.WaitUntilCountOrTimeoutAsync(local_3, millisecondsTimeout, cancellationToken) : (Task <bool>)local_3); } }
public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { CheckDisposed(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } if (cancellationToken.IsCancellationRequested) { return(Task <bool> .FromCancellation(cancellationToken)); } var source = new TaskCompletionSource <bool>(); if (_canEnter.Wait(0, cancellationToken)) { if (TryOffset(-1, out var dummy)) { source.SetResult(true); return(source.Task); } } RootedTimeout.Launch ( () => { try { source.SetResult(false); } catch (InvalidCastException exception) { // Already cancelled GC.KeepAlive(exception); } }, millisecondsTimeout, cancellationToken ); cancellationToken.Register ( () => { try { source.SetCanceled(); } catch (InvalidOperationException exception) { // Already timeout GC.KeepAlive(exception); } } ); AddWaiter(source); return(source.Task); }
public Task WaitAsync(CancellationToken cancellationToken) { CheckDisposed(); if (cancellationToken.IsCancellationRequested) { return(Task.FromCancellation(cancellationToken)); } var source = new TaskCompletionSource <bool>(); cancellationToken.Register(() => source.SetCanceled()); _asyncWaiters.Add(source); return(source.Task); }
public Task <bool> WaitAsync(TimeSpan timeout, CancellationToken cancellationToken) // TODO: Test coverage? { if (cancellationToken.IsCancellationRequested) { return(Task <bool> .FromCancellation(cancellationToken)); } CheckDisposed(); var source = new TaskCompletionSource <bool>(); if (Wait(0, cancellationToken)) { source.SetResult(true); return(source.Task); } Thread.MemoryBarrier(); Theraot.Threading.Timeout.Launch ( () => { try { source.SetResult(false); } catch (InvalidOperationException exception) { // Already cancelled GC.KeepAlive(exception); } }, timeout, cancellationToken ); cancellationToken.Register ( () => { try { source.SetCanceled(); } catch (InvalidOperationException exception) { // Already timeout GC.KeepAlive(exception); } } ); _asyncWaiters.Add(source); return(source.Task); }
public Task <bool> WaitAsync(TimeSpan timeout, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Task <bool> .FromCancellation(cancellationToken)); } CheckDisposed(); var source = new TaskCompletionSource <bool>(); GC.KeepAlive ( new Theraot.Threading.Timeout ( () => { try { source.SetResult(false); } catch (InvalidOperationException exception) { // Already cancelled GC.KeepAlive(exception); } }, timeout, cancellationToken ) { Rooted = true } ); cancellationToken.Register ( () => { try { source.SetCanceled(); } catch (InvalidOperationException exception) { // Already timeout GC.KeepAlive(exception); } } ); _asyncWaiters.Add(source); return(source.Task); }
public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(Task <bool> .FromCancellation(cancellationToken)); } CheckDisposed(); var source = new TaskCompletionSource <bool>(); Theraot.Threading.Timeout.Launch(() => source.SetResult(false), millisecondsTimeout, cancellationToken); cancellationToken.Register(() => source.SetCanceled()); _asyncWaiters.Add(source); return(source.Task); }
/// <summary> /// Asynchronously waits to enter the <see cref="SemaphoreSlim"/>, /// using a 32-bit signed integer to measure the time interval, /// while observing a <see cref="T:System.Threading.CancellationToken"/>. /// </summary> /// <param name="millisecondsTimeout"> /// The number of milliseconds to wait, or <see cref="Timeout.Infinite"/>(-1) to wait indefinitely. /// </param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to observe.</param> /// <returns> /// A task that will complete with a result of true if the current thread successfully entered /// the <see cref="SemaphoreSlim"/>, otherwise with a result of false. /// </returns> /// <exception cref="T:System.ObjectDisposedException">The current instance has already been /// disposed.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a negative number other than -1, /// which represents an infinite time-out. /// </exception> public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { CheckDispose(); // Validate input if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException( nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong); } // Bail early for cancellation if (cancellationToken.IsCancellationRequested) { return(Task.FromCancellation <bool>(cancellationToken)); } using (LockHolder.Hold(m_lock)) { // If there are counts available, allow this waiter to succeed. if (m_currentCount > 0) { --m_currentCount; if (m_waitHandle != null && m_currentCount == 0) { m_waitHandle.Reset(); } return(s_trueTask); } else if (millisecondsTimeout == 0) { // No counts, if timeout is zero fail fast return(s_falseTask); } // If there aren't, create and return a task to the caller. // The task will be completed either when they've successfully acquired // the semaphore or when the timeout expired or cancellation was requested. else { Debug.Assert(m_currentCount == 0, "m_currentCount should never be negative"); var asyncWaiter = CreateAndAddAsyncWaiter(); return((millisecondsTimeout == Timeout.Infinite && !cancellationToken.CanBeCanceled) ? asyncWaiter : WaitUntilCountOrTimeoutAsync(asyncWaiter, millisecondsTimeout, cancellationToken)); } } }
public Task WaitAsync(CancellationToken cancellationToken) // TODO: Test coverage? { CheckDisposed(); if (cancellationToken.IsCancellationRequested) { return(Task.FromCancellation(cancellationToken)); } var source = new TaskCompletionSource <bool>(); if (Wait(0, cancellationToken)) { source.SetResult(true); return(source.Task); } Thread.MemoryBarrier(); cancellationToken.Register(() => source.SetCanceled()); _asyncWaiters.Add(source); return(source.Task); }
public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) // TODO: Test coverage? { if (cancellationToken.IsCancellationRequested) { return(Task <bool> .FromCancellation(cancellationToken)); } CheckDisposed(); var source = new TaskCompletionSource <bool>(); if (TryEnter()) { source.SetResult(true); return(source.Task); } Thread.MemoryBarrier(); Theraot.Threading.Timeout.Launch(() => source.SetResult(false), millisecondsTimeout, cancellationToken); // TODO: Review cancellationToken.Register(() => source.SetCanceled()); _asyncWaiters.Add(source); return(source.Task); }