static AsyncStep GetDequeueStep()
        {
            if (dequeueStep == null)
            {
                dequeueStep = RandomDelayQueuedSendsAsyncResult <TItem> .CallAsync(
                    (thisPtr, t, c, s) => thisPtr.itemQueue.BeginDequeue(TimeSpan.MaxValue, c, s),
                    (thisPtr, r) => thisPtr.currentItem = thisPtr.itemQueue.EndDequeue(r));
            }

            return(dequeueStep);
        }
        static AsyncStep GetSendItemStep()
        {
            if (sendItemStep == null)
            {
                sendItemStep = RandomDelayQueuedSendsAsyncResult <TItem> .CallParallel(
                    (thisPtr, t, c, s) => thisPtr.OnBeginSendItem(thisPtr.currentItem, t, c, s),
                    (thisPtr, r) => thisPtr.OnEndSendItem(r));
            }

            return(sendItemStep);
        }
        static AsyncStep GetDelayStep()
        {
            if (delayStep == null)
            {
                delayStep = RandomDelayQueuedSendsAsyncResult <TItem> .CallAsync(
                    (thisPtr, t, c, s) => thisPtr.BeginDelay(c, s),
                    (thisPtr, r) => thisPtr.EndDelay(r));
            }

            return(delayStep);
        }
            public DelayAsyncResult(
                RandomDelayQueuedSendsAsyncResult <TItem> parent,
                AsyncCallback callback,
                object state)
                : base(callback, state)
            {
                int delay = parent.GetNextDelay();

                if (delay != 0)
                {
                    this.delayTimer = new IOThreadTimer(onDelayCompletedCallback, this, true);
                    this.delayTimer.Set(delay);
                }
                else
                {
                    this.Complete(true);
                }
            }
        protected override IEnumerator <AsyncStep> GetAsyncSteps()
        {
            while (true)
            {
                yield return(RandomDelayQueuedSendsAsyncResult <TItem> .GetDequeueStep());

                if (this.currentItem == null)
                {
                    yield break;
                }

                if (this.doDelay)
                {
                    yield return(RandomDelayQueuedSendsAsyncResult <TItem> .GetDelayStep());
                }

                yield return(RandomDelayQueuedSendsAsyncResult <TItem> .GetSendItemStep());
            }
        }