public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { CheckDisposed(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } if (cancellationToken.IsCancellationRequested) { return(TaskEx.FromCanceled <bool>(cancellationToken)); } var source = new TaskCompletionSource <bool>(); if (_canEnter.Wait(0, cancellationToken) && TryOffset(-1, out var dummy)) { source.SetResult(true); return(source.Task); } RootedTimeout.Launch ( () => { try { source.SetResult(false); } catch (InvalidCastException exception) { // Already canceled No.Op(exception); } }, millisecondsTimeout, cancellationToken ); cancellationToken.Register ( () => { try { source.SetCanceled(); } catch (InvalidOperationException exception) { // Already timeout No.Op(exception); } } ); AddWaiter(source); return(source.Task); }
public Task <bool> WaitAsync(int millisecondsTimeout, CancellationToken cancellationToken) { var state = GetState(); if (millisecondsTimeout < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } if (cancellationToken.IsCancellationRequested) { return(TaskExEx.FromCanceled <bool>(cancellationToken)); } var source = new TaskCompletionSource <bool>(); if (state.CanEnter.Wait(0, cancellationToken) && TryOffset(-1, out var dummy, state)) { source.SetResult(true); return(source.Task); } RootedTimeout.Launch ( () => { try { source.SetResult(false); } catch (InvalidCastException exception) { // Already canceled _ = exception; } }, () => { try { source.SetCanceled(cancellationToken); } catch (InvalidOperationException exception) { // Already timeout _ = exception; } }, millisecondsTimeout, cancellationToken ); state.AsyncWaiters.Add(source); return(source.Task); }
public CancellationTokenSource(int millisecondsDelay) : this() { if (millisecondsDelay < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsDelay)); } if (millisecondsDelay != Timeout.Infinite) { _timeout = RootedTimeout.Launch(Callback, millisecondsDelay); } }
/// <summary> /// Creates a Task that will complete after a time delay. /// </summary> /// <param name="millisecondsDelay">The number of milliseconds to wait before completing the returned Task</param> /// <param name="cancellationToken">The cancellation token that will be checked prior to completing the returned Task</param> /// <returns>A Task that represents the time delay</returns> /// <exception cref="ArgumentOutOfRangeException"> /// The <paramref name="millisecondsDelay" /> is less than -1. /// </exception> /// <exception cref="ObjectDisposedException"> /// The provided <paramref name="cancellationToken" /> has already been disposed. /// </exception> /// <remarks> /// If the cancellation token is signaled before the specified time delay, then the Task is completed in /// Canceled state. Otherwise, the Task is completed in RanToCompletion state once the specified time /// delay has expired. /// </remarks> public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken) { // Throw on non-sensical time if (millisecondsDelay < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsDelay), "The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer."); } Contract.EndContractBlock(); // some short-cuts in case quick completion is in order if (cancellationToken.IsCancellationRequested) { // return a Task created as already-Canceled return(TaskExEx.FromCanceled(cancellationToken)); } if (millisecondsDelay == 0) { // return a Task created as already-RanToCompletion return(TaskExEx.CompletedTask); } var source = new TaskCompletionSource <bool>(); if (cancellationToken.CanBeCanceled) { source.Task.AssignCancellationToken(cancellationToken, null, null); } var timeout = RootedTimeout.Launch ( () => source.TrySetResult(true), () => source.TrySetCanceled(), millisecondsDelay, cancellationToken ); source.Task.SetPromiseCheck(() => timeout.CheckRemaining()); return(source.Task); }
public void CancelAfter(int millisecondsDelay) { if (millisecondsDelay < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsDelay)); } CheckDisposed(); if (Volatile.Read(ref _cancelRequested) == 0 && millisecondsDelay != Timeout.Infinite) { if (_timeout == null) { // Have to be careful not to create secondary background timer var newTimer = RootedTimeout.Launch(Callback, Timeout.Infinite); var oldTimer = Interlocked.CompareExchange(ref _timeout, newTimer, null); if (oldTimer != null) { newTimer.Cancel(); } _timeout.Change(millisecondsDelay); } } }
public static void CancelAfter(this CancellationTokenSource cancellationTokenSource, TimeSpan delay) { if (cancellationTokenSource == null) { throw new NullReferenceException(); } GC.KeepAlive(cancellationTokenSource.Token); RootedTimeout.Launch ( () => { try { cancellationTokenSource.Cancel(); } catch (ObjectDisposedException exception) { No.Op(exception); } }, delay ); }
/// <summary> /// Creates a Task that will complete after a time delay. /// </summary> /// <param name="millisecondsDelay">The number of milliseconds to wait before completing the returned Task</param> /// <param name="cancellationToken">The cancellation token that will be checked prior to completing the returned Task</param> /// <returns>A Task that represents the time delay</returns> /// <exception cref="T:System.ArgumentOutOfRangeException"> /// The <paramref name="millisecondsDelay"/> is less than -1. /// </exception> /// <exception cref="T:System.ObjectDisposedException"> /// The provided <paramref name="cancellationToken"/> has already been disposed. /// </exception> /// <remarks> /// If the cancellation token is signaled before the specified time delay, then the Task is completed in /// Canceled state. Otherwise, the Task is completed in RanToCompletion state once the specified time /// delay has expired. /// </remarks> public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken) { // Throw on non-sensical time if (millisecondsDelay < -1) { throw new ArgumentOutOfRangeException(nameof(millisecondsDelay), "The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer."); } Contract.EndContractBlock(); // some short-cuts in case quick completion is in order if (cancellationToken.IsCancellationRequested) { // return a Task created as already-Canceled return(FromCancellation(cancellationToken)); } if (millisecondsDelay == 0) { // return a Task created as already-RanToCompletion return(CompletedTask); } var source = new TaskCompletionSource <bool>(); if (millisecondsDelay > 0) { var timeout = RootedTimeout.Launch ( () => { try { source.SetResult(true); } catch (InvalidOperationException exception) { // Already cancelled GC.KeepAlive(exception); } }, millisecondsDelay, cancellationToken ); source.Task.SetPromiseCheck(() => timeout.CheckRemaining()); } if (cancellationToken.CanBeCanceled) { cancellationToken.Register ( () => { try { source.SetCanceled(); } catch (InvalidOperationException exception) { // Already timeout GC.KeepAlive(exception); } } ); } return(source.Task); }
public static void CancelAfter(this CancellationTokenSource cancellationToken, TimeSpan delay) { RootedTimeout.Launch(cancellationToken.Cancel, delay); }
public static void CancelAfter(this CancellationTokenSource cancellationToken, int millisecondsDelay) { RootedTimeout.Launch(cancellationToken.Cancel, millisecondsDelay); }