public void Set()
        {
            AsyncAutoResetEventState toRelease = null;

            lock (waits)
            {
                if (waits.Count > 0)
                {
                    toRelease = waits[0];
                    waits.RemoveAt(0);
                }
                else if (!signaled)
                {
                    signaled = true;
                }
            }

            if (toRelease != null)
            {
                toRelease.TaskCompletion.SetResult(true);

                if (toRelease.TimeoutTimer != null)
                {
                    toRelease.TimeoutTimer.Change(Timeout.Infinite, Timeout.Infinite);
                    toRelease.TimeoutTimer.Dispose();
                }
            }
        }
        public Task<bool> WaitAsync(int timeout)
        {
            lock (waits)
            {
                if (signaled)
                {
                    signaled = false;
                    return completed;
                }
                else
                {
                    var tcs = new AsyncAutoResetEventState()
                    {
                        TaskCompletion = new TaskCompletionSource<bool>()
                    };
                    if (timeout != Timeout.Infinite)
                    {
                        tcs.TimeoutTimer = new Timer(OnTimeoutTimer_Elapsed, tcs, timeout, Timeout.Infinite);
                    }
                    waits.Add(tcs);

                    return tcs.TaskCompletion.Task;
                }
            }
        }
        public Task <bool> WaitAsync(int timeout)
        {
            lock (waits)
            {
                if (signaled)
                {
                    signaled = false;
                    return(completed);
                }
                else
                {
                    var tcs = new AsyncAutoResetEventState()
                    {
                        TaskCompletion = new TaskCompletionSource <bool>()
                    };
                    if (timeout != Timeout.Infinite)
                    {
                        tcs.TimeoutTimer = new Timer(OnTimeoutTimer_Elapsed, tcs, timeout, Timeout.Infinite);
                    }
                    waits.Add(tcs);

                    return(tcs.TaskCompletion.Task);
                }
            }
        }