protected override IEnumerator <AsyncStep> GetAsyncSteps()
            {
                this.discoveryClientChannelBase.InitializeAndFindAsync();

                while (true)
                {
                    this.currentEndpointDiscoveryMetadata = null;
                    yield return(DiscoveryChannelBuilderAsyncResult.GetDequeueStep());

                    Exception ex = this.CheckEndpointDiscoveryMetadataAndGetException();
                    if (ex != null)
                    {
                        this.CompleteOnce(ex);
                        yield break;
                    }

                    bool checkListenUris = (currentEndpointDiscoveryMetadata.ListenUris.Count > 0);
                    int  index           = 0;

                    do
                    {
                        if (checkListenUris)
                        {
                            this.CreateChannel(
                                this.currentEndpointDiscoveryMetadata.Address,
                                this.currentEndpointDiscoveryMetadata.ListenUris[index++]);
                        }
                        else
                        {
                            this.CreateChannel(
                                this.currentEndpointDiscoveryMetadata.Address,
                                this.currentEndpointDiscoveryMetadata.Address.Uri);
                        }

                        if (this.innerChannel != null)
                        {
                            yield return(DiscoveryChannelBuilderAsyncResult.GetOpenStep());

                            if (this.innerChannel != null)
                            {
                                // The channel was successfully opened
                                if (TD.InnerChannelOpenSucceededIsEnabled())
                                {
                                    TD.InnerChannelOpenSucceeded(
                                        this.currentEndpointDiscoveryMetadata.Address.ToString(),
                                        GetVia(this.innerChannel).ToString());
                                }

                                yield break;
                            }
                        }
                    }while (index < this.currentEndpointDiscoveryMetadata.ListenUris.Count);
                }
            }
        public TChannel BuildChannel(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            this.InitializeAndFindAsync();

            TChannel innerChannel = null;
            bool     completed    = false;

            EndpointDiscoveryMetadata currentEndpointDiscoveryMetadata = null;

            try
            {
                do
                {
                    try
                    {
                        currentEndpointDiscoveryMetadata = this.discoveredEndpoints.Dequeue(timeoutHelper.RemainingTime());
                    }
                    catch (TimeoutException te)
                    {
                        throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout), te));
                    }

                    if (currentEndpointDiscoveryMetadata == null)
                    {
                        if (this.totalDiscoveredEndpoints < 1)
                        {
                            throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DiscoveryClientChannelEndpointNotFound, this.exception));
                        }
                        else
                        {
                            throw FxTrace.Exception.AsError(new EndpointNotFoundException(SR.DiscoveryClientChannelCreationFailed(this.totalDiscoveredEndpoints), this.exception));
                        }
                    }

                    if (timeoutHelper.RemainingTime() == TimeSpan.Zero)
                    {
                        throw FxTrace.Exception.AsError(new TimeoutException(SR.DiscoveryClientChannelOpenTimeout(timeoutHelper.OriginalTimeout)));
                    }

                    if (currentEndpointDiscoveryMetadata.ListenUris.Count == 0)
                    {
                        completed = this.CreateChannel(
                            ref innerChannel,
                            currentEndpointDiscoveryMetadata.Address,
                            currentEndpointDiscoveryMetadata.Address.Uri,
                            timeoutHelper);
                    }
                    else
                    {
                        foreach (Uri listenUri in currentEndpointDiscoveryMetadata.ListenUris)
                        {
                            completed = this.CreateChannel(
                                ref innerChannel,
                                currentEndpointDiscoveryMetadata.Address,
                                listenUri,
                                timeoutHelper);

                            if (completed)
                            {
                                break;
                            }
                        }
                    }
                }while (!completed);
            }
            finally
            {
                if (completed && TD.InnerChannelOpenSucceededIsEnabled())
                {
                    TD.InnerChannelOpenSucceeded(
                        currentEndpointDiscoveryMetadata.Address.ToString(),
                        GetVia(innerChannel).ToString());
                }

                this.Cleanup(timeoutHelper.RemainingTime());
            }

            return(innerChannel);
        }