public Task<Token> AcquireAsync()
        {
            this.comingRequest = new AcquireRequest();
            Task<Token> resultTask = this.comingRequest.AcquireTask;
            lock (this.acquireRequests)
            {
                if (this.processingRequest == null)
                {
                    this.processingRequest = this.comingRequest;
                    this.comingRequest.GrantRequestAndRunContinuation();
                }
                else
                {
                    this.acquireRequests.Enqueue(this.comingRequest);
                }
            }

            return resultTask;
        }
        public void Release(Token token)
        {
            if (this.processingRequest != token)
            {
                throw new InvalidOperationException("Invalid owner token");
            }

            lock (this.acquireRequests)
            {
                // need to clean it before grant the next request!!
                this.processingRequest = null;

                if (this.acquireRequests.Count > 0)
                {
                    this.processingRequest = this.acquireRequests.Dequeue();
                }
            }

            if (this.processingRequest != null)
            {
                // to prevent deadlocks, you should generally avoid running arbitrary user code such as event handlers or in this case, continuations, under a lock
                this.processingRequest.GrantRequestAndRunContinuation();
            }
        }