/// <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);
        }