protected override IEnumerator <AsyncStep> GetAsyncSteps() { this.shouldContinue = true; while (this.shouldContinue) { this.internalMessage = null; yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.inputQueue.BeginDequeue(TimeSpan.MaxValue, c, s), (thisPtr, r) => thisPtr.internalMessage = thisPtr.owner.inputQueue.EndDequeue(r), ExceptionPolicy.Continue)); if (this.LastAsyncStepException != null) { Log.MessageDispatcherDequeueException(this.LastAsyncStepException); } if (this.internalMessage == null) { break; } yield return(this.CallAsync( (thisPtr, t, c, s) => { Task task = this.owner.onReceivedAsync(internalMessage.Stream, internalMessage.Id, internalMessage.Messages); return new TaskAsyncResult(task, c, s); }, (thisPtr, r) => TaskAsyncResult.End(r), ExceptionPolicy.Continue)); if (this.LastAsyncStepException != null) { Log.MessageDispatcherErrorInCallback(this.LastAsyncStepException); } } }
protected override IEnumerator <AsyncStep> GetAsyncSteps() { while (this.shouldContinuePump) { // Reset status for the loop this.brokeredMessage = null; // Receives the message yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.receiver.BeginReceive(c, s), (thisPtr, r) => thisPtr.brokeredMessage = thisPtr.owner.receiver.EndReceive(r), ExceptionPolicy.Continue)); if (this.LastAsyncStepException != null) { Log.MessagePumpReceiveException(this.owner.id, this.LastAsyncStepException); if (ShouldBackoff(this.LastAsyncStepException)) { Log.MessagePumpBackoff(BackoffAmount, this.LastAsyncStepException); yield return(this.CallAsyncSleep(BackoffAmount)); } } // Retry next receive if no message was received. if (this.brokeredMessage == null) { continue; } // Handles the message InternalMessage internalMessage = null; try { ulong sequenceNumber = (ulong)brokeredMessage.SequenceNumber; Message[] messages = MessageConverter.ToMessages(brokeredMessage); internalMessage = new InternalMessage(this.owner.id, sequenceNumber, messages); } catch (Exception e) { Log.MessagePumpDeserializationException(e); } finally { brokeredMessage.Dispose(); } if (internalMessage != null) { if (!this.owner.semaphore.TryEnter()) { yield return(this.CallAsync( (thisPtr, t, c, s) => thisPtr.owner.semaphore.BeginEnter(c, s), (thisPtr, r) => thisPtr.owner.semaphore.EndEnter(r), ExceptionPolicy.Transfer)); } this.owner.inputQueue.EnqueueAndDispatch(internalMessage, this.owner.exitSemaphore); } } }