/// <summary> /// Waits for the value to change /// </summary> /// <param name="timeout">The amount of time to wait for the event to be set</param> /// <param name="token">A cancellation token to abort waiting</param> /// <returns>A task that returns True when the value has changed, or False if the timeout elapsed</returns> /// <exception cref="OperationCanceledException">The given cancellation token was cancelled</exception> /// <exception cref="TimeoutException">The timeout elapsed</exception> public ValueTask <bool> Wait(TimeSpan timeout, CancellationToken token = default) { if (_State == null) { throw new ObjectDisposedException(nameof(AsyncValue <T>), "Value has been disposed of"); } var Instance = AsyncValueInstance.GetOrCreate(this); var ValueTask = new ValueTask <bool>(Instance, Instance.Version); Instance.ApplyCancellation(token, timeout); // Not set, add ourselves to the queue waiting _Waiters.Enqueue(Instance); return(ValueTask); }
/// <summary> /// Waits for the event to become set, or if set return immediately /// </summary> /// <param name="value">The value to check for</param> /// <param name="timeout">The amount of time to wait for the event to be set</param> /// <param name="token">A cancellation token to abort waiting</param> /// <returns>A task that completes when the event has been set</returns> /// <exception cref="OperationCanceledException">The given cancellation token was cancelled</exception> public ValueTask <bool> WaitUnless(T value, TimeSpan timeout, CancellationToken token = default) { if (_Comparer.Equals(value, Value)) { return(new ValueTask <bool>(true)); } var Instance = AsyncValueInstance.GetOrCreate(this); var ValueTask = new ValueTask <bool>(Instance, Instance.Version); if (!ValueTask.IsCompleted) { Instance.ApplyCancellation(token, timeout); // Not set, add ourselves to the queue waiting _Waiters.Enqueue(Instance); // Did the event become set while we were busy? var State = _State; if (State == null) { _Waiters.Erase(Instance); Instance.SetDisposed(); } else if (_Comparer.Equals(value, State.Value)) { _Waiters.Erase(Instance); Instance.SetCompleted(); } } return(ValueTask); }